/*! bui-editor - v0.0.1 - 2019-07-20 09:07:58 
Copyright (c): kevin.huang  www.vvui.net 
Released under MIT License*/
(function (global, factory) {
	if (typeof define === 'function' && define.amd  && !window['_all_in_']) {
		define(['$B', 'toolbar', 'panel', 'colorpicker', 'plugin', 'utils', 'resize', 'mutilUpload', 'editConfig'], function (_$B) {
			return factory(global, _$B);
		});
	} else {
		if (!global['$B']) {
			global['$B'] = {};
		}
		factory(global, global['$B']);
	}
}(typeof window !== 'undefined' ? window : this, function (window, $B) {
/***
 * 2019-06-08 修复插入浮动图片，遗漏onSuccess回调的bug
 * 富文本的常量等定义，该文件作为合并文件的头部文件
 * @Author: kevin.huang 
 * ****/
'use strict';
var VERVar = 'bui-editor-0.0.1';
var VERSite = 'www.vvui.net';
var VERDate = '2019-07-20';

if (navigator.userAgent.indexOf("Firefox") > 0) {
    document.designMode = "on";
    document.execCommand('enableObjectResizing', false, 'false');
    document.designMode = "off";
}
function fixIeResizeBug(el) {
    if ($B.isIE()) {
        el.onresizestart = function (e) {
            return false;
        };
    }
}
var chSeqArray = ["一", "二", "三", "四", "五", "六", "七", "八", "九", "十"];
var tmpChSeqArray = [], chSeqItem, tmpChSeq;
chSeqItem = "十";
for (var _j = 0; _j < 9; _j++) {
    tmpChSeq = chSeqItem + chSeqArray[_j];
    tmpChSeqArray.push(tmpChSeq);
}
for (var _k = 1; _k < 9; _k++) {
    chSeqItem = chSeqArray[_k] + "十";
    tmpChSeqArray.push(chSeqItem);
    for (_j = 0; _j < 9; _j++) {
        tmpChSeq = chSeqItem + chSeqArray[_j];
        tmpChSeqArray.push(tmpChSeq);
    }
}
chSeqArray = chSeqArray.concat(tmpChSeqArray);
tmpChSeqArray = undefined;
/***
 * 获取下一个中文序列的chSeqArray数组下标
 * chSeq:当前序列
 * return {
 *      index : chSeqArray 下标
 *      seq : 序列
 * }
 * ***/
function getChNextSeq(chSeq) {
    var index, seq;
    for (var i = 0; i < 98; ++i) {
        if (chSeq === chSeqArray[i]) {
            index = i + 1;
            seq = chSeqArray[index];
        }
    }
    return {
        index: index,
        seq: seq
    };
}
/**
 * 获取中文序列的下标
 * ***/
function getChSeqIndex(chSeq) {
    var index;
    for (var i = 0; i < 98; ++i) {
        if (chSeq === chSeqArray[i]) {
            index = i;
        }
    }
    return index;
}
var testSeq = "^[\\s*\\u200b]*(\\d+|[一二三四五六七八九十]+)\\s*$";
var seqexp = "^\\s*[\\(（\\s*]*((\\d+|[一二三四五六七八九十]+)\\s*[\\.、\\)）])\\s*";
var elementToTargets = {
    "SPAN": true,
    "TD": true,
    "A": true
};
var titleArray = [{
    txt: '正文',
    v: {
        "line-height": "25.2px",
        "font-size": "14px",
        "font-weight": "400"
    }
}, {
    txt: '标题1',
    v: {
        "line-height": "50.4px",
        "font-size": "28px",
        "font-weight": "700"
    }
}, {
    txt: '标题2',
    v: {
        "line-height": "43.2px",
        "font-size": "24px",
        "font-weight": "700"
    }
}, {
    txt: '标题3',
    v: {
        "line-height": "39.6px",
        "font-size": "22px",
        "font-weight": "700"
    }
}, {
    txt: '标题4',
    v: {
        "line-height": "36px",
        "font-size": "20px",
        "font-weight": "700"
    }
}, {
    txt: '标题5',
    v: {
        "line-height": "32.4px",
        "font-size": "18px",
        "font-weight": "700"
    }
}, {
    txt: '标题6',
    v: {
        "line-height": "28.8px",
        "font-size": "16px",
        "font-weight": "700"
    }
}, {
    txt: '标题7',
    v: {
        "line-height": "25.2px",
        "font-size": "14px",
        "font-weight": "700"
    }
}
];
var fontsFamilyMap = [{
    txt: "微软雅黑",
    v: "微软雅黑,Microsoft YaHei"
}, {
    txt: "华文宋体",
    v: "宋体,SimSun"
},
{
    txt: "华文楷体",
    v: "楷体,楷体_GB2312,SimKai"
}, {
    "txt": "黑体",
    v: "黑体,SimHei"
},
{
    txt: "隶书",
    v: "隶书,SimLi"
}, {
    txt: "Comic Sans MS",
    v: "Comic Sans MS"
},
{
    txt: "Verdana",
    v: "Verdana"
}, {
    txt: "Arial",
    v: "Arial"
}
];
var fontsMap = [{
    txt: "8号",
    v: "11px"
}, {
    "txt": "9号",
    v: "12px"
},
{
    txt: "10号",
    v: "13px"
}, {
    txt: "11号",
    v: "14px"
},
{
    txt: "12号",
    v: "16px"
}, {
    txt: "13号",
    v: "18px"
},
{
    txt: "14号",
    v: "20px"
}, {
    txt: "15号",
    v: "22px"
},
{
    txt: "16号",
    v: "24px"
}, {
    txt: "17号",
    v: "28px"
}, {
    txt: "18号",
    v: "32px"
}
];
var legalCssStyleNames = ['border-width', 'background','border-style', 'border-color', 'line-through', 'width', 'height', 'border-bottom', 'border-top', 'border-right', 'border-left', 'border-collapse', 'font-family', 'font-size', 'font-weight', 'font-style', 'text-decoration', 'background-color', 'color', 'text-align', 'list-style-position'];
var pLegalCssStyleNames = ['line-height','background', 'padding-top', 'padding-bottom', 'padding-right', 'padding-left', 'padding', 'margin-right', 'margin-left', 'margin-bottom', 'margin-top', 'margin', 'border-top', 'border-right', 'border-bottom', 'border-left', 'border', 'text-indent'];
var legalFontFamilys = ['宋体', '微软雅黑', '黑体', '楷体', 'Arial', 'Verdana', '"Times New Roman"', 'Consolas'];
var fontSizePt2Px = {
    '7.5': '10px',
    '8': '11px',
    '9': '12px',
    '10': '12.5px',
    '10.5': '14px',
    '11': '14.7px',
    '12': '16px',
    '13': '17px',
    '13.5': '18px',
    '14': '18.7px',
    '14.5': '19px',
    '15': '20px',
    '16': '21.3px',
    '17': '23px',
    '18': '24px',
    '20': '26.7px',
    '22': '29.3px',
    '24': '32px',
    '26': '34.7px',
    '27': '36px',
    '28': '37.3px',
    '29': '38px',
    '30': '40px',
    '32': '42px',
    '34': '45px',
    '36': '48px',
    '42': '56px',
    '48': '64px',
    '72': '96px'
};
var legalFontWeights = ['bold', 'normal', '700', '400'];
var legalFontStyles = ['italic', 'normal'];
var legalTextDecorations = ['line-through', 'underline', 'none'];
var legalTextAligns = ['center', 'left', 'right', 'justify'];
var legalAttr = ["type", "closed", "closed_count", "closed_status", "id", "class", "style", "tabindex", "w", "h", "col", "row", "href", "src", "target", "colspan", "rowspan", "contenteditable"];

var cssloadString;
/**提取当前页面中需要用到的css链接**/
function getCssloadString(flowScriptSrcs) {
    if (!flowScriptSrcs && cssloadString) {
        return cssloadString;
    }    
    var cssPath = [];
    $("link.k_bui_css").each(function () {
        cssPath.push($(this).attr("href"));
    });
    if(flowScriptSrcs){
        cssPath.push(flowScriptSrcs.flowcss);        
    }
    var linkArr = [],i,len,path;
    linkArr.push('<body onload="' + 'var d=document;var head=d.getElementsByTagName(\'head\')[0];var link;');
    for (i = 0, len = cssPath.length; i < len; ++i) {
         path = cssPath[i];
        linkArr.push('link=d.createElement(\'link\');link.type=\'text/css\';link.rel=\'stylesheet\';link.href=\'' + path + '\';head.appendChild(link);');
    }
    if(flowScriptSrcs){      
        var jsPath =  flowScriptSrcs.src;      
        for (i = 0, len = jsPath.length; i < len; ++i) {
            path = jsPath[i];
            linkArr.push('s=d.createElement(\'script\');s.defer=\'defer\';s.type=\'text/javascript\';s.src=\'' + path + '\';head.appendChild(s);');
        }
    }
    linkArr.push('">');
    if(flowScriptSrcs){
        linkArr.push(flowScriptSrcs.struct);
    }
    linkArr.push('</body>');
    if(flowScriptSrcs){
        linkArr.push(flowScriptSrcs.onloadScript);
    }
    var resouce = linkArr.join("");
    if(!flowScriptSrcs){
        cssloadString = resouce;
    }
    return resouce;
}
function getUUID() {
    return "k_" + $B.generateDateUUID("ddhhmmssSS", 10);
}
var eConfig = $B.editConfig;
var $body;
function _getBody() {
    if (!$body) {
        $body = $(window.document.body).css("position", "relative");
    }
    return $body;
}
//将默认的defaultStyle 转为Object
var styleArray = eConfig.defaultStyle.split(";");
var defaultStyleObject = {}, _s1, tmpS1Arr;
for (var startI = 0, tmpLen = styleArray.length; startI < tmpLen; ++startI) {
    _s1 = styleArray[startI];
    if (_s1 !== "") {
        tmpS1Arr = _s1.split(":");
        defaultStyleObject[$.trim(tmpS1Arr[0])] = $.trim(tmpS1Arr[1]).toLowerCase();
    }
}
/**临时阻止默认的右键***/
var stopDefaultctxMenu = function (e) {
    _getBody().on("contextmenu.edit", function () {
        return false;
    });
    setTimeout(function () {
        _getBody().off("contextmenu.edit");
    }, 800);
};
/**
 * 公共变量
 * **/
var head = $("head");
var userAgent = navigator.userAgent;
var selectDataKey = "_exist_*_";
var sectionTag = "DIV";
var extCopyCfg = {
    "": 1,
    "line-height": 1,
    "text-indent": 1,
    "margin-top": 1,
    "margin-bottom": 1,
    "border-width": 1,
    "border-color": 1,
    "border-style": 1
};
var config = {
    tools: {
        save: {
            icon: 'fa-floppy',
            params: {
                undo: false,
                needRange: false
            }
        },
        paintBrush: {
            icon: 'fa-brush',
            params: {
                undo: true,
                needRange: true
            }
        },
        clear: {
            icon: 'fa-trash-empty',
            params: {
                undo: true,
                needRange: false
            }
        },
        source: {
            icon: 'fa-code',
            params: {
                undo: false,
                needRange: false
            }
        },
        undo: {
            icon: 'fa-ccw-1',
            params: {
                undo: false,
                needRange: false
            },
            disabled: true
        },
        redo: {
            icon: 'fa-cw-1',
            params: {
                undo: false,
                needRange: false
            },
            disabled: true
        },
        bold: {
            icon: 'fa-bold',
            params: {
                undo: true
            }
        },
        italic: {
            icon: 'fa-italic',
            params: {
                undo: true
            }
        },
        underline: {
            icon: 'fa-underline',
            params: {
                undo: true
            }
        },
        strikethrough: {
            icon: 'fa-strike',
            params: {
                undo: true
            }
        },
        superscript: {
            icon: 'fa-superscript',
            params: {
                undo: true
            }
        },
        subscript: {
            icon: 'fa-subscript',
            params: {
                undo: true
            }
        },
        fontFamily: {
            icon: 'fa-angle-down',
            click: 'showFontFamilyPanel',
            params: {
                undo: true
            }
        },
        fontSize: {
            icon: 'fa-angle-down',
            click: 'showFontSizePanel',
            params: {
                undo: true
            }
        },
        fontTitle: {
            icon: 'fa-angle-down',
            click: 'showTitlePanel',
            params: {
                undo: true
            }
        },
        fontSpace: {
            icon: 'fa-text-width-1',
            click: 'showFontSpacePanel',
            params: {
                undo: true
            }
        },
        fontColor: {
            icon: 'fa-pencil',
            click: 'showColorPickerPanel',
            params: {
                delayUndo: true,
                delay: 1000
            }
        },
        backgroundColor: {
            icon: 'fa-pencil-squared',
            click: 'showColorPickerPanel',
            params: {
                delayUndo: true,
                delay: 1000
            }
        },
        paragraph: {
            icon: 'fa-doc-text',
            click: 'showParagraphPanel',
            params: {
                undo: true,
                needRange: false,
                createTargetsByRange: true
            }
        },
        insertTable: {
            icon: 'fa-table',
            click: 'showTablePanel',
            params: {
                undo: true,
                needRange: false
            }
        },
        eraser: {
            icon: 'fa-eraser',
            params: {
                undo: true,
                needRange: false
            }
        },
        orderList: {
            icon: 'fa-list-numbered',
            click: "showOrderListPanel",
            params: {
                undo: true,
                needRange: false
            }
        },
        unorderList: {
            icon: 'fa-list-bullet',
            click: "showUnorderListPanel",
            params: {
                undo: true,
                needRange: false
            }
        },
        alignCenter: {
            icon: 'fa-align-center',
            params: {
                undo: true,
                needRange: false,
                css: {
                    "text-align": "center"
                }
            }
        },
        alignJustify: {
            icon: 'fa-align-justify',
            params: {
                undo: true,
                needRange: false,
                css: {
                    "text-align": "justify"
                }
            }
        },
        alignLeft: {
            icon: 'fa-align-left',
            params: {
                undo: true,
                needRange: false,
                css: {
                    "text-align": "left"
                }
            }
        },
        alignRight: {
            icon: 'fa-align-right',
            params: {
                undo: true,
                needRange: false,
                css: {
                    "text-align": "right"
                }
            }
        },
        link: {
            icon: 'fa-link',
            params: {
                undo: false,
                needRange: false
            }
        },
        picture: {
            icon: 'fa-file-image',
            click: 'showInsertImage',
            params: {
                undo: false,
                needRange: false
            }
        },
        upload: {
            icon: 'fa-upload',
            click: 'showUploadFile',
            params: {
                undo: false,
                needRange: false
            }
        },
        emotion: {
            icon: 'fa-smile',
            click: 'showEmotion',
            params: {
                undo: false,
                needRange: false
            }
        },
        video: {
            icon: 'fa-video',
            click: 'showUploadVideo',
            params: {
                undo: false,
                needRange: false
            }
        },
        split: {
            icon: 'fa-minus',
            params: {
                undo: false,
                needRange: false
            }
        },
        insertIcon: {
            icon: 'fa-heart-empty',
            click: 'showIcon',
            params: {
                undo: false,
                needRange: false
            }
        },
        map: {
            icon: 'fa-location-alt',
            click: 'showMap',
            params: {
                undo: false,
                needRange: false
            }
        },
        insertCode: {
            icon: 'fa-file-code',
            click: 'showCode',
            params: {
                undo: false,
                needRange: false
            }
        },
        insertFloat: {
            icon: 'fa-docs',
            click: 'showFloatPanel',
            params: {
                undo: true
            }
        },
        mobile: {
            icon: ' fa-login-1',
            click: "showPhoneListPanel",
            params: {
                undo: false,
                needRange: false
            }
        },
        flow:{
            icon: 'fa-shuffle',
            params: {
                undo: false,
                needRange: false
            }
        },
        preview: {
            icon: 'fa-eye',
            params: {
                undo: false,
                needRange: false
            }
        },
        fullprint: {
            icon: 'fa-resize-full',
            params: {
                undo: false,
                needRange: false
            }
        },
        help: {
            icon: 'fa-question',
            params: {
                undo: false,
                needRange: false
            }
        }
    },
    mouseMenu: [{
        icon: 'fa-table',
        title: eConfig.label.insertTable,
        handler: 'insertTable',
        params: {
            undo: true,
            needRange: false,
            col: 3,
            row: 3
        }
    }, {
        icon: 'fa-file-image',
        title: eConfig.label.insertImage,
        handler: 'showInsertImageWindow',
        params: {
            undo: true,
            needRange: false
        }
    }, {
        icon: 'fa-upload',
        title: eConfig.label.insertFile,
        handler: 'showInsertFileWindow',
        params: {
            undo: true,
            needRange: false
        }
    }, {
        icon: 'fa-link',
        title: eConfig.label.insertLink,
        handler: 'link',
        params: {
            undo: false,
            needRange: false
        }
    }, {
        icon: 'fa-edit',
        title: eConfig.label.editLink,
        handler: 'editLink',
        params: {
            undo: false,
            needRange: false
        }
    }, {
        icon: 'fa-unlink',
        title: eConfig.label.unLink,
        handler: 'unlink',
        params: {
            undo: false,
            needRange: false
        }
    }, {
        icon: 'fa-smile',
        title: eConfig.label.insertEmotion,
        handler: 'showEmotionWindow',
        params: {
            undo: false,
            needRange: false
        }
    }, {
        icon: 'fa-exchange',
        title: eConfig.label.setSectionWidth,
        tip: eConfig.label.ssTip,
        handler: 'setSectionWidth',
        params: {
            undo: false,
            needRange: false
        }
    }, {
        icon: 'fa-resize-horizontal',
        title: eConfig.label.resetSectionWidth,
        tip: eConfig.label.sssTip,
        handler: 'resetSectionWidth',
        params: {
            undo: true,
            needRange: false
        }
    }, {
        icon: 'fa-move',
        title: eConfig.label.move,
        tip: eConfig.label.moveTip,
        handler: 'setSectionMove',
        params: {
            undo: false,
            needRange: false
        }
    },
    {
        icon: 'fa-down',
        title: eConfig.label.closedNext,
        tip: eConfig.label.closeNextTip,
        handler: 'closedNext',
        params: {
            undo: false,
            needRange: false
        }
    }, {
        icon: 'fa-doc-text',
        title: eConfig.label.paragraph,
        tip: eConfig.label.paragraphTip,
        handler: 'openParagrapWindow',
        params: {
            undo: false,
            needRange: false
        }
    }]
};
var dropDownControlHtml = "<div style='width:auto;' class='k_edit_tools_tip_wrapper k_edit_tools_drop_wrapper  k_box_shadow'><div class='k_edit_tools_drop_caret'><i class='fa fa-up-dir'></i></div><div class='k_edit_tools_drop_item_wrap'></div></div>";
var defaultOpts = {
    width: 600,
    height: 400,
    undoSize: 20,
    mobile: false,
    onFormCreated: function () { }
};
function getSingleton(className, editor) {
    var key = "_" + className + "_";
    if (window[key]) {
        return window[key];
    }
    var obj = new window[className](editor);
    window[key] = obj;
    return obj;
}
function Toolbars(edit) {
    $B.extend(this, Toolbars); //继承父类 
    this.edit = edit;
    this.$wrap = $("<div tabindex='0' style='z-index:2' class='k_box_size k_edit_tools_wrap'></div>").appendTo(edit.jqObj);
    this.opts = edit.opts;
    var _this = this;
    this.buttons = {};
    var models = this.opts.tools ? this.opts.tools : eConfig.tools;
    this.toolbarStyle = this.edit.opts.toolbarStyle;
    var hideMouseIt = {
        insertTable: true,
        showInsertImageWindow: true,
        showInsertFileWindow: true,
        link: true,
        showEmotionWindow: true
    };
    Object.keys(models).forEach(function (key) {
        var title = models[key];
        var go = true;
        if (key === "mobile") {//非移动适配模式
            go = edit.opts.mobile;
        }
        if (go) {
            var it = config.tools[key];
            if (it) {
                it.title = title;
                _this.createTool(it, key);
                if (key === "insertTable") {
                    hideMouseIt.insertTable = false;
                } else if (key === "link") {
                    hideMouseIt.link = false;
                } else if (key === "picture") {
                    hideMouseIt.showInsertImageWindow = false;
                } else if (key === "upload") {
                    hideMouseIt.showInsertFileWindow = false;
                } else if (key === "emotion") {
                    hideMouseIt.showEmotionWindow = false;
                }
            }
        }
    });
    //版本说明    
    _this.createTool({icon: "fa-info-circled", params: {undo:false,needRange:false}, title: eConfig.label.version},"showVersion");
    this.edit.defaultHideMouseIts = [];//根据配置隐藏鼠标右键菜单对应的项目
    window["_bui_"]=true;
    Object.keys(hideMouseIt).forEach(function (key) {
        if (hideMouseIt[key]) {
            _this.edit.defaultHideMouseIts.push(key);
        }
    });
    this.tip = $("<div style='width:auto;max-width:120px;position:absolute;top:-500px;' class='k_edit_tools_tip_wrapper' disabled='disabled'><div class='k_edit_tools_tip_caret'><i style='height:5px;' class='fa fa-up-dir'></i></div><div class='k_edit_tools_tip_text'></div></div>").appendTo(_getBody()).hide();
    this.$wrap.mouseleave(function (e) {
        if ($(e.target).hasClass("k_edit_tools_wrap")) {
            _this.hideTip();
            _this._hideDropList();
        }
    }).on("click", function (e) {
        _this.hideTip();
        _this._hideAllDropList();
    }).focus(function () {
        _this.edit.rebuildUserRange();
    });
    this.tip.mouseleave(function () {
        _this.hideTip();
    });
    //颜色控件
    this.ColorPickerPanel = new $B.ColorPicker(undefined, {
        update2Target: false,
        showCaret: true,
        positionFix: {
            top: 2,
            left: 1
        },
        onfocus: function () {
            _this.edit.rebuildUserRange();
        },
        mouseenter: function () {
            clearTimeout(_this.hideDropDownListTimer);
        },
        change: function (val) {
            var $t = _this.currentClickBtn;
            var method = $t.data("method");
            var params = $t.data("params");
            if (typeof params === "undefined") {
                params = {};
            }
            params["color"] = val;
            _this.edit.execute(method, params);
            $t.children("h1").css("background", val);
        },
        onStartFn: function () {
            _this.edit._makeUndoDataByFocus();
        }
    });
    this.ColorPickerPanel["name"] = "kedit main ColorPicker";
    this.ColorPickerPanel.setValue({
        hex: "#051F7C"
    });
    this.ColorPickerPanel.jqObj.addClass("k_edit_panel_border_top");
    this.allPanels = {
        "ColorPickerPanel": this.ColorPickerPanel
    };
}
Toolbars.prototype = {
    constructor: Toolbars,
    destroy: function () {
        var _this = this;
        Object.keys(_this.allPanels).forEach(function (key) {
            if (key !== "ColorPickerPanel") {
                _this.allPanels[key].remove();
            }
        });
        this.tip.remove();
        this.ColorPickerPanel.destroy();
        this.super.destroy.call(this);
    },
    hideTip: function (t) {
        this.tip.hide();
    },
    /**点击事件监听
     * 收起下拉框，修饰联动
     * ***/
    clickSubscribe: function (edit, rangeCss) {
        this._hideDropList();
        this.hideTip();
        var i, len, item;
        var titleBtn = this.buttons["fontTitle"];
        //console.log(" clickSubscribe  >>>> clickSubscribe");
        var titleTxt = titleArray[0].txt;
        if (rangeCss.fontTitle) {
            var f = rangeCss.fontTitle;
            for (i = 0, len = titleArray.length; i < len; ++i) {
                item = titleArray[i];
                if (item.v["font-size"] === f["font-size"] && item.v["font-weight"] === f["font-weight"]) {
                    titleTxt = item.txt;
                    break;
                }
            }
        }
        if (titleBtn) {
            titleBtn.children("span").text(titleTxt);
        }
        var boldBtn = this.buttons["bold"];
        if (boldBtn) {
            if (rangeCss["font-weight"] && rangeCss["font-weight"] === "700") {
                boldBtn.addClass("k_edit_tools_item_actived");
            } else {
                boldBtn.removeClass("k_edit_tools_item_actived");
            }
        }

        var italicBtn = this.buttons["italic"];
        if (italicBtn) {
            if (rangeCss["font-style"] && rangeCss["font-style"] === "italic") {
                italicBtn.addClass("k_edit_tools_item_actived");
            } else {
                italicBtn.removeClass("k_edit_tools_item_actived");
            }
        }

        var underlineBtn = this.buttons["underline"];
        if (underlineBtn) {
            if (rangeCss["text-decoration"] && rangeCss["text-decoration"].indexOf("underline") > -1) {
                underlineBtn.addClass("k_edit_tools_item_actived");
            } else {
                underlineBtn.removeClass("k_edit_tools_item_actived");
            }
        }
        var strikethroughBtn = this.buttons["strikethrough"];
        if (strikethroughBtn) {
            if (rangeCss["text-decoration"] && rangeCss["text-decoration"].indexOf("line-through") > -1) {
                strikethroughBtn.addClass("k_edit_tools_item_actived");
            } else {
                strikethroughBtn.removeClass("k_edit_tools_item_actived");
            }
        }
        var verticalAlign = rangeCss["vertical-align"];
        var superscriptBtn = this.buttons["superscript"];
        if (superscriptBtn) {
            if (verticalAlign && verticalAlign === "super") {
                superscriptBtn.addClass("k_edit_tools_item_actived");
            } else {
                superscriptBtn.removeClass("k_edit_tools_item_actived");
            }
        }
        var subscriptBtn = this.buttons["subscript"];
        if (subscriptBtn) {
            if (verticalAlign && verticalAlign === "sub") {
                subscriptBtn.addClass("k_edit_tools_item_actived");
            } else {
                subscriptBtn.removeClass("k_edit_tools_item_actived");
            }
        }

        var fontFamilyBtn = this.buttons["fontFamily"];
        var fontFamily = rangeCss["font-family"];
        if (fontFamilyBtn) {
            if (fontFamily) {
                fontFamily = fontFamily.toLowerCase().replace(/,\s*/g, ",").replace(/"/g, "");
                for (i = 0, len = fontsFamilyMap.length; i < len; ++i) {
                    item = fontsFamilyMap[i];
                    if (item.v.toLowerCase().indexOf(fontFamily) >= 0) {
                        fontFamilyBtn.children("span").text(item.txt);
                        break;
                    }
                }
            } else {
                for (i = 0, len = fontsFamilyMap.length; i < len; ++i) {
                    item = fontsFamilyMap[i];
                    if (item.v.toLowerCase().indexOf(defaultStyleObject["font-family"]) >= 0) {
                        fontFamilyBtn.children("span").text(item.txt);
                        break;
                    }
                }
            }
        }

        var fontSizeBtn = this.buttons["fontSize"];
        if (fontSizeBtn) {
            var fsize = rangeCss["font-size"];
            if (fsize) {
                for (i = 0, len = fontsMap.length; i < len; ++i) {
                    item = fontsMap[i];
                    if (item.v.toLowerCase().indexOf(fsize) >= 0) {
                        fontSizeBtn.children("span").text(item.txt);
                        break;
                    }
                }
            }
        }
        var fontColorBtn = this.buttons["fontColor"];
        if (fontColorBtn) {
            var color = rangeCss["color"];
            fontColorBtn.children("h1").css("background", color);
        }
        var backgroundColorBtn = this.buttons["backgroundColor"];
        if (backgroundColorBtn) {
            var bColor = rangeCss["background-color"];
            backgroundColorBtn.children("h1").css("background-color", bColor);
        }
        // var orderListBtn = this.buttons["orderList"];
        // var unorderListBtn = this.buttons["unorderList"];
        var alignCenterBtn = this.buttons["alignCenter"];
        var alignLeftBtn = this.buttons["alignLeft"];
        var alignRightBtn = this.buttons["alignRight"];
        var textAlign = rangeCss["text-align"];
        if (alignCenterBtn) {
            if (textAlign === "center") {
                alignCenterBtn.addClass("k_edit_tools_item_actived");
            } else {
                alignCenterBtn.removeClass("k_edit_tools_item_actived");
            }
        }
        if (alignLeftBtn) {
            if (textAlign === "left" || textAlign === "start") {
                alignLeftBtn.addClass("k_edit_tools_item_actived");
            } else {
                alignLeftBtn.removeClass("k_edit_tools_item_actived");
            }
        }
        if (alignRightBtn) {
            if (textAlign === "right") {
                alignRightBtn.addClass("k_edit_tools_item_actived");
            } else {
                alignRightBtn.removeClass("k_edit_tools_item_actived");
            }
        }
    },
    _dropDownControlMouseenter: function (e) {
        clearTimeout(e.data.seft.hideDropDownListTimer);
    },
    /**关闭所有下来列表***/
    _hideAllDropList: function () {
        var _this = this;
        Object.keys(_this.allPanels).forEach(function (key) {
            _this.allPanels[key].hide();
        });
    },
    /**关闭列表
     * handler：对应的处理函数名称，去掉show即为panel的key
     * **/
    _hideDropList: function (handler) {
        handler = handler ? handler : '';
        var timer = 200;
        if (handler !== "") {
            timer = 0;
        }
        var _this = this;
        function a() {
            var panelObjName = handler.replace("show", "");
            Object.keys(_this.allPanels).forEach(function (key) {
                if (key !== panelObjName) {
                    _this.allPanels[key].hide();
                }
            });
        }
        if (timer > 0) {
            _this.hideDropDownListTimer = setTimeout(function () {
                a();
            }, timer);
        } else {
            a();
        }
    },
    _focus: function () {
        $(this).data("self").edit.rebuildUserRange();
        return false;
    },
    /**调用edit对应的处理API
     * 如果有handler参数则先调用toolbar的handler，handler里面再调用edit的处理api
     * 这里是工具栏通向edit的入口
     * **/
    _click: function () {
        var $t = $(this);
        var _this = $t.data("self");
        if (_this.edit.activedMenu && _this.edit.activedMenu[0] !== this) {
            _this.edit.activedMenu.removeClass("k_edit_btn_actived");
            _this.edit.brushCss = undefined;
        }
        _this.tip.hide();
        var handler = $t.data("handler");
        _this._hideDropList(handler);
        _this.currentClickBtn = $t;
        if ($t.hasClass("k_edit_tools_disabled")) {
            return false;
        }
        var method = $t.data("method");
        var params = $t.data("params");
        if (typeof params === "undefined") {
            params = {};
        }
        //如果存在handler则执行handler，由handler里面再调用edit.execute
        if (typeof _this[handler] === "function") {
            _this[handler](method, params, $t);
        } else {
            _this.edit.execute(method, params, $t);
        }
        return false;
    },
    createTool: function (it, key, borderColor) {      
        var _this = this;
        var height;
        var btn = $("<div key='" + key + "' style='padding-bottom:2px;cursor:pointer;position:relative;border:1px solid " + borderColor + "' tabindex='0' _title='" + it.title + "' class='k_box_size k_edit_tools_item'><i class='fa " + it.icon + "'></i></div>");
        if (this.toolbarStyle) {
            // btn.children("i").css(this.toolbarStyle);
            // btn.css("line-height","1.3em");
            btn.addClass("k_edit_toolbar_style");
            if (this.toolbarStyle.margin) {
                btn.css("margin", this.toolbarStyle.margin);
            }
            if (this.toolbarStyle.size) {
                btn.css({ "height": this.toolbarStyle.size });
            }
            var style = '.k_edit_toolbar_style {line-height:1.3em;}';
            style = style + '.k_edit_toolbar_style i {font-size:' + this.toolbarStyle["font-size"] + ';color:' + this.toolbarStyle["color"] + ';}';
            style = style + ".k_edit_tools_disabled i {color: #ccc !important;cursor: not-allowed;} .k_edit_btn_actived i {color: red  !important;}";
            head.children("#k_edit_diy_toolbar").remove();
            head.append("<style id='k_edit_diy_toolbar'>" + style + "</style>");
        }
        btn.appendTo(this.$wrap).mouseover(function (e) {
            var $t = $(this);
            var ofs = $t.offset();
            var title = $t.attr("_title");
            _this.tip.css({
                top: ofs.top + height,
                left: ofs.left
            });
            _this.tip.children(".k_edit_tools_tip_text").text(title);
            _this.tip.show();          
        }).mouseleave(function (e) {
            if ($(e.target).hasClass("k_edit_tools_item")) {
                //console.log(" mouseout mouseout mouseout");
                // _this.hideTip();
                //_this.tip.hide();
                //_this._hideDropList();
            }
            return false;
        }).data("method", key)
            .data("handler", it.click)
            .data("params", it.params)
            .data("self", _this);
        if (it.disabled) {
            btn.addClass("k_edit_tools_disabled");
        }
        btn.on("focus", _this._focus);
        btn.on("click", _this._click);
        height = btn.height();
        this.buttons[key] = btn;
        var i, len, item;
        if (key === "fontFamily") {
            for (i = 0, len = fontsFamilyMap.length; i < len; ++i) {
                item = fontsFamilyMap[i];
                if (item.v.toLowerCase().indexOf(defaultStyleObject["font-family"]) >= 0) {
                    btn.prepend("<span>" + item.txt + "</span>");
                    break;
                }
            }
        } else if (key === "fontTitle") {
            btn.prepend("<span>" + titleArray[0].txt + "</span>");
        } else if (key === "fontSize") {
            for (i = 0, len = fontsMap.length; i < len; ++i) {
                item = fontsMap[i];
                if (item.v.toLowerCase().indexOf(defaultStyleObject["font-size"]) >= 0) {
                    btn.prepend("<span>" + item.txt + "</span>");
                    break;
                }
            }
        } else if (key === "fontColor") {
            btn.append("<h1 class='k_box_size' style='bottom: -3px;position:absolute;border: 1px solid rgb(204, 204, 204);width:100%;height:4px;margin:0px;padding:0;background:" + defaultStyleObject["color"] + "'></h1>");
        } else if (key === "backgroundColor") {
            btn.append("<h1 class='k_box_size' style='bottom: -3px;position:absolute;border: 1px solid rgb(204, 204, 204);width:100%;height:4px;margin:0px;padding:0;background:" + defaultStyleObject["background-color"] + "'></h1>");
        }
        return btn;
    },
    notifyTools: function (args) {
        var operator = args["operator"];
        var params = args["params"];
        if (this[operator + "Notify"]) {
            this[operator + "Notify"](params);
        }
    },
    _changeUndoRedoBtns: function (params) {
        if (params.undoStackSize === 0) {
            this.buttons["undo"].addClass("k_edit_tools_disabled");
        } else {
            this.buttons["undo"].removeClass("k_edit_tools_disabled");
        }
        if (params.redoStackSize === 0) {
            this.buttons["redo"].addClass("k_edit_tools_disabled");
        } else {
            this.buttons["redo"].removeClass("k_edit_tools_disabled");
        }
    },
    redoNotify: function (params) {
        this._changeUndoRedoBtns(params);
    },
    undoNotify: function (params) {
        this._changeUndoRedoBtns(params);
    },
    _onfocus: function () {
        var seft = $(this).data("seft");
        if (seft) {
            seft.edit.rebuildUserRange();
        }
        if (this.tagName === "INPUT") {
            this.focus();
        }
    },
    _bindFocus: function (jqObj) {
        var _this = this;
        if (!jqObj.attr("_focus")) {
            jqObj.on("focus", _this._onfocus)
                .data("seft", _this).attr("tabindex", 0).attr("_focus", "true");
            jqObj.children().each(function () {
                _this._bindFocus($(this));
            });
        }
    },
    showColorPickerPanel: function (method, params) {
        this.ColorPickerPanel.show(this.currentClickBtn, {
            top: 5
        });
    },
    _createDropPanel: function (itemsArray, method, params, panelName, getItemHtmlFn) {
        var _this = this;
        var panel = $(dropDownControlHtml).appendTo(_getBody());
        panel.on("mouseenter", {
            seft: this
        }, this._dropDownControlMouseenter);
        panel.mouseleave(function () {
            _this._hideDropList();
            //console.log("panel.mouseout >>>>>>>panel.mouseout");
        });
        var wrap = panel.children(".k_edit_tools_drop_item_wrap");
        if (typeof itemsArray === "function") {
            itemsArray(wrap, params);
            _this._bindFocus(wrap);
        } else {
            var _click = function () {
                var $t = $(this);
                params[$t.data("_name")] = $t.data("_value");
                _this.edit.execute(method, params);
                if (method === "fontFamily" || method === "fontSize" || method === "fontTitle") {
                    _this.buttons[method].children("span").text($t.text());
                }
                clearTimeout(_this._hideDropListTimer);
                _this._hideDropListTimer = setTimeout(function () {
                    _this._hideDropList();
                }, 2000);
            };
            for (var i = 0, len = itemsArray.length; i < len; ++i) {
                var $html = getItemHtmlFn.call(wrap, itemsArray[i]);
                $html.appendTo(wrap);
                if (!$html.data("unbind_")) {
                    $html.click(_click).data("seft", _this);
                }
            }
            _this._bindFocus(wrap);
        }
        this.allPanels[panelName] = panel;
        return panel;
    },
    _showOrHidePanel: function ($panel, $btn, onShowFn) {
        if ($panel.css("display") === "none") {
            var ofs = $btn.offset();
            ofs.top = ofs.top + $btn.outerHeight() + 10;
            $panel.css(ofs).show();
            if (onShowFn) {
                onShowFn($panel);
            }
            this.tip.hide();
        } else {
            $panel.slideUp();
        }
    },
    showFontFamilyPanel: function (method, params, $btn) {
        if (!this.FontFamilyPanel) {
            this.FontFamilyPanel = this._createDropPanel(fontsFamilyMap, method, params, "FontFamilyPanel", function (it) {
                var $it = $("<div tabindex='0' style='font-family:" + it.v + "' class='k_edit_tools_drop_item'>" + it.txt + "</div>");
                $it.data("_value", it.v).data("_name", "font-family");
                return $it;
            });
        }
        this._showOrHidePanel(this.FontFamilyPanel, $btn);
    },
    showFontSizePanel: function (method, params, $btn) {
        if (!this.FontSizePanel) {
            this.FontSizePanel = this._createDropPanel(fontsMap, method, params, "FontSizePanel", function (it) {
                var $it = $("<div tabindex='0' style='font-size:" + it.v + "' class='k_edit_tools_drop_item'>" + it.txt + "</div>");
                $it.data("_value", it.v).data("_name", "font-size");
                return $it;
            });
        }
        this._showOrHidePanel(this.FontSizePanel, $btn);
    },
    showTitlePanel: function (method, params, $btn) {
        if (!this.FontTitlePanel) {
            this.FontTitlePanel = this._createDropPanel(titleArray, method, params, "FontTitlePanel", function (it) {
                var $it = $("<div tabindex='0' class='k_edit_tools_drop_item'>" + it.txt + "</div>").css(it.v);
                $it.data("_value", it.v).data("_name", "font-title");
                return $it;
            });
        }
        this._showOrHidePanel(this.FontTitlePanel, $btn);
    },
    showFontSpacePanel: function (method, params, $btn) {
        if (!this.FontSpacePanel) {
            var _this = this;
            var clickFn = function () {
                var $t = $(this);
                var id = $t.attr("id");
                var cmd, nextAll, user2;
                if (id && id === "_123") {
                    cmd = "reset";
                    nextAll = $t.nextAll();
                } else {
                    nextAll = $t.parent().nextAll();
                    if ($t.hasClass("reduce")) {
                        cmd = "reduce";
                    } else {
                        cmd = "accretion";
                    }
                }
                nextAll.find("._user2").each(function () {
                    var $s = $(this);
                    if ($s.children("i").hasClass("fa-ok-circled")) {
                        user2 = $s.attr("value");
                    }
                });
                params["cmd"] = cmd;
                params["user2"] = user2;
                _this.edit.execute(method, params);
            };
            this.FontSpacePanel = this._createDropPanel([{ i: 0 }, { i: 1 }, { i: 2 }], method, params, "FontSpacePanel", function (it) {
                var $it;
                if (it.i === 0) {
                    $it = $("<div id='_123' tabindex='0' class='k_edit_tools_drop_item'><i style='padding-right:6px;' class='fa fa-arrows-ccw'></i>" + eConfig.label.reset + "</div>");
                    $it.on("click", clickFn);
                } else if (it.i === 1) {
                    $it = $("<div tabindex='0' class='k_edit_tools_drop_item clearfix'><div title='" + eConfig.label.reduce + "' class='k_box_size reduce' style='width:50%;float:left;padding-right:5px;text-align:center;'><i class='fa fa-left'></i></div><div title='" + eConfig.label.accretion + "' style='width:50%;float:right;text-align:center' class='k_box_size'><i style='padding-left:5px;' class='fa fa-right'></i></div></div>");
                    $it.children("div").click(clickFn);
                } else {
                    $it = $("<div id='_000_' tabindex='0' class='k_edit_tools_drop_item'>应用于:<br/><span class='_user2' value='1' style='padding-right:3px'>选区<i class='fa fa-ok-circled'></i></span><span class='_user2' value='2'>段落<i class='fa fa-circle-empty'></i></span></div>");
                    $it.children("span").click(function () {
                        var $t = $(this);
                        var $i = $t.children("i");
                        if ($i.hasClass("fa-ok-circled")) {
                            $i.removeClass("fa-ok-circled").addClass("fa-circle-empty");
                            $t.siblings("span").children("i").removeClass("fa-circle-empty").addClass("fa-ok-circled");
                        } else {
                            $i.removeClass("fa-circle-empty").addClass("fa-ok-circled");
                            $t.siblings("span").children("i").removeClass("fa-ok-circled").addClass("fa-circle-empty");
                        }
                    });
                }
                $it.data("unbind_", true);
                return $it;
            });
        }
        this._showOrHidePanel(this.FontSpacePanel, $btn);
    },
    showFloatPanel: function (method, params, $btn) {
        if (!this.FloatPanel) {
            var _this = this;
            var clickFn = function () {
                var id = $(this).attr("id");
                if (id === '_f_txt') {
                    _this.edit.insertFloatText();
                } else {
                    _this.edit.insertFloatImg();
                }
                _this.FloatPanel.hide();
            };
            this.FloatPanel = this._createDropPanel([{ i: 0 }, { i: 1 }], method, params, "FontSpacePanel", function (it) {
                var $it;
                if (it.i === 0) {
                    $it = $("<div tabindex='0' id='_f_txt' class='k_edit_tools_drop_item'><i class='fa fa-doc-text' style='padding:2px 4px'></i>" + eConfig.label.insertFloatText + "</div>");
                } else if (it.i === 1) {
                    $it = $("<div tabindex='0' id='_f_img' class='k_edit_tools_drop_item'><i class='fa fa-file-image'  style='padding:2px 4px'></i>" + eConfig.label.insertFloatImg + "</div>");
                }
                $it.data("unbind_", true);
                $it.click(clickFn);
                return $it;
            });
        }
        this._showOrHidePanel(this.FloatPanel, $btn);
    },
    showTablePanel: function (method, params, $btn) {
        var _this = this;
        var tip;
        if (!this.TablePanel) {
            this.TablePanel = this._createDropPanel(function (wrap) {
                var $tab = $("<table  class='k_edit_table_set'></table>");
                for (var i = 0, len = 15; i < len; ++i) {
                    var $tr = $("<tr row='" + i + "'></tr>");
                    for (var j = 0, jlen = 15; j < jlen; ++j) {
                        $("<td col='" + j + "'></td>").appendTo($tr);
                    }
                    $tr.appendTo($tab);
                }
                $tab.appendTo(wrap);
                var tdArray = $tab.find("td");
                var col = 1;
                var row = 1;
                tdArray.mousemove(function () {
                    tdArray.removeClass("selectd");
                    var $td = $(this);
                    $td.addClass("selectd").prevAll().addClass("selectd");
                    col = parseInt($td.attr("col"));
                    var tr = $td.parent();
                    row = parseInt(tr.attr("row")) + 1;
                    tr.prevAll().each(function () {
                        $(this).children().each(function (i) {
                            var td = $(this);
                            td.addClass("selectd");
                            if (i >= col) {
                                return false;
                            }
                        });
                    });
                    tip.text(eConfig.insertTableTip.replace("x", row).replace("y", (col + 1)));
                }).click(function () {
                    params["col"] = col + 1;
                    params["row"] = row;
                    _this.edit.execute(method, params);
                    _this.TablePanel.hide();
                });
                tip = $("<div style='line-height:18px;text-align:center;font-size:12px;'></div>").appendTo(wrap);
            });
        }
        this.TablePanel.find(".selectd").removeClass("selectd");
        this._showOrHidePanel(this.TablePanel, $btn);
    },
    showParagraphPanel: function (method, params, $btn) {
        //修改为 弹窗方式，支持边框设置功能 2019-03-03
        this.edit.openParagrapWindow(method, params, $btn);
    },
    showOrderListPanel: function (method, params, $btn) {
        if (!this.OrderListPanel) {
            var _this = this;
            this.OrderListPanel = this._createDropPanel(function (wrap, params) {
                var list = [{
                    txt: eConfig.label.listNum,
                    v: "1"
                },
                {
                    "txt": eConfig.label.listLm,
                    v: "i"
                },
                {
                    txt: eConfig.label.listEn,
                    v: "a"
                },
                {
                    txt: eConfig.label.listNone,
                    v: "none"
                }];
                var ul = $('<ul style="list-style-type:none;"/>').appendTo(wrap);
                var clickFn = function () {
                    var $t = $(this);
                    var type = $t.attr("_type");
                    params["list-style-type"] = type;
                    _this.edit.execute(method, params);
                };
                for (var i = 0, len = list.length; i < len; ++i) {
                    var it = list[i];
                    var txt = it.txt;
                    if (it.v === "none") {
                        txt = "<i style='padding-right:6px;' class='fa icon-minus-sign'></i>" + txt;
                    } else if (it.v === "a") {
                        txt = "<i style='padding-right:6px;' class='fa icon-sort-by-alphabet'></i>" + txt;
                    } else if (it.v === "i") {
                        txt = "<i style='padding-right:6px;' class='fa icon-info'></i>" + txt;
                    } else {
                        txt = "<i style='padding-right:6px;' class='fa icon-sort-by-order'></i>" + txt;
                    }
                    var li = $("<li style='padding:2px 16px;' _type='" + it.v + "'>" + txt + "</li>").appendTo(ul);
                    li.click(clickFn);
                }
            }, method, params, "OrderListPanel");
        }
        this._showOrHidePanel(this.OrderListPanel, $btn);
    },
    showUnorderListPanel: function (method, params, $btn) {
        if (!this.UnorderListPanel) {
            var _this = this;
            this.UnorderListPanel = this._createDropPanel(function (wrap, params) {
                var list = [{
                    txt: eConfig.label.disc,
                    v: "disc"
                },
                {
                    "txt": eConfig.label.circle,
                    v: "circle"
                },
                {
                    txt: eConfig.label.square,
                    v: "square"
                },
                {
                    txt: eConfig.label.none,
                    v: "none"
                }
                ];
                var ul = $('<ul style="list-style-position:inside;padding:0;margin:0;"/>').appendTo(wrap);
                var clickFn = function () {
                    var $t = $(this);
                    var type = $t.css("list-style-type");
                    params["list-style-type"] = type;
                    _this.edit.execute(method, params);
                };
                for (var i = 0, len = list.length; i < len; ++i) {
                    var it = list[i];
                    var txt = it.txt;
                    if (it.v === "none") {
                        txt = "<i style='padding-right:6px;' class='fa icon-minus-sign'></i>" + txt;
                    }
                    var li = $("<li style='padding:2px 16px;list-style-type:" + it.v + "'>" + txt + "</li>").appendTo(ul);
                    li.click(clickFn);
                }
            }, method, params, "UnorderListPanel");
        }
        this._showOrHidePanel(this.UnorderListPanel, $btn);
    },
    showEmotion: function (method, params, $btn) {
        this.edit.openEmotionWindow(method, params, $btn);
    },
    showIcon: function (method, params, $btn) {
        this.edit.openIconWindow("insertIcon", params, $btn);
    },
    showCode: function (method, params, $btn) {
        this.edit.openCodeWindow(method, params, $btn);
    },
    showMap: function (method, params, $btn) {
        this.edit.openMapWindow(method, params, $btn);
    },
    showUploadVideo: function (method, params, $btn) {
        if (!window["videojs"]) {
            $B.error(eConfig.label.videoWarning);
            return;
        }
        this.edit.showUploadVideo(method, params, $btn);
    },
    showUploadFile: function (method, params, $btn) {
        this.edit.openInsertFileWindow(method, params, $btn);
    },
    showInsertImage: function (method, params, $btn) {
        this.edit.openInsertImageWindow(method, params, $btn);
    },
    showPhoneListPanel: function (method, params, $btn) {
        if (!this.PhoneListPanel) {
            var _this = this;
            var mobiles = eConfig.mobiles;
            this.PhoneListPanel = this._createDropPanel(mobiles, method, params, "PhoneListPanel", function (it) {
                var $it = $("<div tabindex='0' class='k_edit_tools_drop_item'>" + it.title + "</div>");
                $it.data("_value", it.size).data("_name", "phonesize").attr("title", it.size);
                return $it;
            });
        }
        this._showOrHidePanel(this.PhoneListPanel, $btn);

    },
    height: function () {
        return this.$wrap.outerHeight();
    }
};
var Kedit = function (jqObj, opts) {
    $B.extend(this, Kedit); //继承父类 
    var contents = jqObj.children().remove();
    var _this = this;
    this.doc = $(document);
    var  $w = window;
    this.opts = $.extend({}, defaultOpts, opts);
    this.jqObj = jqObj.addClass("k_box_size k_edit_main_wrap").css({
        width: this.opts.width,
        height: this.opts.height
    });
    var inputWrap = $("<div class='k_box_size k_edit_input_wrap' spellcheck='false' style='overflow: auto;position:absolute;top:0;left:0;width:100%;height:100%;z-index:1'></div>");
    this.$input = $("<div spellcheck='false' contenteditable='true' style='overflow:visible;width:100%;min-height:100%;' class='k_box_size k_edit_input_filed'></div>").appendTo(inputWrap);
    this.$fixInput = this.$input;//区分固定，浮动输入框
    if(this.opts.mobile){
       this.$fixInput.addClass("k_dropdown_shadow");      
    }
    this.$inputWrap = inputWrap;
    this.tools = undefined;
    this.id = getUUID();
    this.undoStack = new Stack(this.opts.undoSize);
    this.redoStack = new Stack(this.opts.undoSize);
    inputWrap.appendTo(this.jqObj);
    this.range = undefined;
    this.painTargets = []; //选区内所有需要修饰的元素   
    this.tables = [];
    this.windowArray = [];
    this.clickActivedObject = undefined; //当前点击激活的表格,图像
    this._initInputEvents(this.$input);
    if (this.opts.createToolbars) {
        this.tools = this.opts.createToolbars(this);
    } else {
        this.tools = new Toolbars(this);
    }
    if (this.tools && this.tools.height) {
        var height = this.tools.height();
        inputWrap.css("border-top", (height + 4) + "px solid #fff");
        if(height === 0){ //修复在隐藏tab里面创建 高度为0的bug
            var fixHeightIvt = setInterval(function(){
                if(_this.tools){
                    height = _this.tools.height();
                    if(height > 0){
                        inputWrap.css("border-top", (height + 4) + "px solid #fff");
                        clearInterval(fixHeightIvt);
                    }       
                }else{
                    clearInterval(fixHeightIvt);
                }                        
            },300);
        }
    }
    setTimeout(function () {
        if (contents.length > 0) {
            _this.setContent(contents);
        }
        _this.insertPElement();
    }, 1);
    window["curEditor"] = this;
    $(document).on("mousedown."+this.id ,function(e){//处理 margin-left区域鼠标点击事件
        //console.log("document mouse down >>>>");
        var pageX = e.pageX;
        var pageY = e.pageY;
        var ofs = _this.jqObj.offset();
        var w = _this.jqObj.width();
        var h = _this.jqObj.height();
        if(ofs.left < pageX  && pageX < ( ofs.left + w)   && pageY < (ofs.top + h) && pageY > ofs.top){
            stopDefaultctxMenu();
            //console.log("document mouse down >>>>>>>");
        }
    });
    if(this.opts.mobile){
        for(var i = 0 , len = eConfig.mobiles.length ; i < len ;++i){
            if(eConfig.mobiles[i].default){
                this.mobile({phonesize : eConfig.mobiles[i].size}); 
                break;
            }
        }
    }
    this.FLOW_CACHE = {};
    $w["_b_u_i_editor__"]=1;
    this._cache_clearner = setInterval(function(){
        var keys = Object.keys(_this.FLOW_CACHE);
        for(var i = 0 ,len = keys.length ; i < len ;++i){
           if(inputWrap.find("#"+keys[i]).length === 0 ){
               delete _this.FLOW_CACHE[keys[i]];
           }
        }
    },300000);
};
Kedit.prototype = {
    constructor: Kedit, 
    /**内容发生变化
     * skip：是否跳过 _setCurrentHtml() 调用
     * ***/
    _onChange: function (skip) {
        if (this.opts.onChange) {
            var _this = this;
            if(!skip){
                this._setCurrentHtml();
            }           
            clearTimeout(this.onChangeTimer);
            this.onChangeTimer = setTimeout(function () {
                var content = _this.getContent();
                _this.opts.onChange(content);
            },500);
        }
    },
    /**
     * 先提前需要保持的html
     * ***/
    _setCurrentHtml:function(){
        this.currentHTML =  this.$fixInput.children().clone();
        this.currentFloatHTML = this.$inputWrap.children(".k_edit_float_panel").clone();
    },
    _clearCurrentHtml:function(){
        this.currentHTML =  undefined;
        this.currentFloatHTML = undefined;
    },
    /**
     * 禁用工具栏按钮
     * ***/
    disabledFunc: function (enabledList) {
        this.tools.$wrap.children("div").each(function () {
            var $t = $(this);
            var key = $t.attr("key");
            if (!enabledList[key] && key !== "redo" && key !== "undo") {
                $t.addClass("k_edit_tools_disabled");
            }
        });
    },
    /***
     * 启用工具栏按钮
     * **/
    enabledFunc: function () {
        this.tools.$wrap.children("div").each(function () {
            var $t = $(this);
            var key = $t.attr("key");
            if (key !== "redo" && key !== "undo") {
                $t.removeClass("k_edit_tools_disabled");
            }
        });
    },
    /**
    * 创建浮动窗口
    * **/
    _createFloatWindow: function (width, height) {
        if (!this.floatTools) {
            this.floatTools = new FloatTools(this);
        }
        if (!this.floatPropPanel) {
            this.floatPropPanel = new FloatPropPanel(this);
        }
        var left,top;
        if(this.opts.mobile){//移动设备模拟
            var inputWidth = this.$fixInput.width();
            var inputHeight = this.$fixInput.height();
            width = inputWidth *  0.6 ;
            height = inputHeight *  0.2 ;
            left = parseInt(this.$fixInput.css("margin-left").replace("px","")) + (inputWidth -  width) / 2 ;
            top = 60 + this.$inputWrap.scrollTop();
        }else{
            left = (this.$fixInput.width() - 400) / 2 + this.$inputWrap.scrollLeft();
            top = 100 + this.$inputWrap.scrollTop();
        }
        var uuid = getUUID();
        var wrap = $("<div id='"+uuid+"' class='k_box_shadow k_edit_float_panel' style='-moz-box-shadow: 0px 0px 3px 3px #D8D8D8;-webkit-box-shadow: 0px 0px 3px 3px #D8D8D8;box-shadow: 0px 0px 3px 3px #D8D8D8;z-index:20000000;background:none;width:" + width + "px;height:" + height + "px;position:absolute;top:" + top + "px;left:" + left + "px;'></div>");
        $("<div class='k_float_opacity_' style='width:100%;height:100%;position:absolute;z-index:20000000;background:#fff;top:0;left:0;-moz-opacity: 0.5;-khtml-opacity: 0.5;opacity: 0.5;'></div>").appendTo(wrap);
        wrap.appendTo(this.$inputWrap);
        this._bindFlowWrapEvnets(wrap);
        setTimeout(function () {
            wrap.trigger("mouseup");
        }, 10);
        return wrap;
    },
    /***绑定浮动框事件**/
    _bindFlowWrapEvnets: function (wrap) {
        var _this = this;
        wrap.mouseup(function () {
            var box = $(this);
            var matrix = box.css("transform");
            var angle = $B.getMatrixAngle(matrix);
            if (angle === 0) {//角度为0才可以resize
                _this._createResizeBox(box);
                _this["resizeBox"].bind(box);
            }
            _this.floatTools.show(box);
        });
    },
    /***
     * 绑定浮动框 顶部拖动工具条事件
     * **/
    _bindFloatPanelEvents: function (wrap) {
        if (!this.floatTools) {
            this.floatTools = new FloatTools(this);
        }
        if (!this.floatPropPanel) {
            this.floatPropPanel = new FloatPropPanel(this);
        }
        this._bindFlowWrapEvnets(wrap);
        var wrapInner = wrap.children("div").eq(1);
        var isImg = wrapInner.children("img").length > 0;
        if (isImg) {//图片
            wrapInner.addClass("k_editor_float_img_wrap k_box_size");
            this._bindFlowImgEvents(wrapInner);
        } else {//
            wrapInner.addClass("k_editor_float_input k_box_size").attr({
                "spellcheck": "false",
                "contenteditable": "true"
            });
            this._initInputEvents(wrapInner);
            return wrapInner;
        }
    },
    /**
     * 创建resizeBox
     * **/
    _createResizeBox: function (box) {
        if (!this["resizeBox"]) {
            var _this = this;
            var resize = new $B.Resize({
                target: box,
                zoomScale: false,
                dragStart: function (args) {
                    _this.resizing = true;
                    if (_this["tipWindow"]) {
                        _this["tipWindow"].hide();
                    }
                },
                dragEnd: function (args) {
                    _this.resizing = false;
                    if (_this.floatTools && resize.target.hasClass("k_edit_float_panel")) {
                        if (_this.floatTools.wrap.css("display") !== "none") {
                            _this.floatTools.show(resize.target);
                        }
                    } else {
                        var box = _this["resizeBox"];
                        if (box.target[0].tagName === "VIDEO") {//如果是视频拖动
                            var width = box.line1.width();
                            var height = box.line2.height();
                            var player = box.target.parent().parent().data("player");
                            player.width(width);
                            player.height(height);
                        }
                    }
                    resize.bind(resize.target);
                },
                onDrag: function () {
                    var box = _this["resizeBox"];
                    if (box.target[0].tagName === "VIDEO") {//如果是视频拖动
                        return false;//阻止更新
                    }
                    return true;
                }
            });
            this["resizeBox"] = resize;
            //this["resizeBox"].disable("left");
        } else {
            this["resizeBox"].bind(box);
        }
    },
    /***更新元素el的id***/
    _updateId: function (el) {
        if (el[0].tagName !== "BR") {
            var _this = this;
            var id = getUUID();
            el.attr("id", id);
            el.children().each(function () {
                _this._updateId($(this));
            });
        }
    },
    /***
     * 从数组中
     * 移除无用的table/image等组件
     * ***/
    removeUselessComponent: function () {
        var _this = this;
        clearTimeout(this["rmUselesscomTimer"]);
        this["rmUselesscomTimer"] = setTimeout(function () {
            var newTablesArray = [];
            for (var i = 0, len = _this.tables.length; i < len; ++i) {
                var comp = _this.tables[i];
                var jqObj = comp.jqObj;
                var p = jqObj.parent();
                if (p.length !== 0) {
                    newTablesArray.push(comp);
                } else {
                    comp.destroy();
                }
            }
            _this.tables = newTablesArray;
        }, 1000);
    },
    /**
     * 打开提示窗口
     * args = {
     *      top:,
     *      left:
     * }
     * createFn创建tip内容的函数
     * **/
    openTIPWindow: function (pos, createFn) {
        var _this = this;
        if (!this["tipWindow"]) {
            this["tipWindow"] = $("<div style='width:auto;' class='k_edit_window k_box_size k_box_shadow'><div style='border:0;position:static;padding:0 12px;' class='k_edit_window_body k_box_size'></div></div>");
            this["tipWindow"].appendTo(_getBody());
            this["tipWindow"].on("mousedown", function () {
                stopDefaultctxMenu();
            });
        }
        var body = this["tipWindow"].children();
        body.children().detach();
        createFn(body, pos);
        body.children().show();
        this["tipWindow"].css(pos).fadeTo(300, 1);
    },
    /**关闭tip窗口**/
    closeTIPWindow: function () {
        var _this = this;
        if (this["tipWindow"] && this["tipWindow"].css("display") === "block") {
            this["tipWindow"].fadeTo(100, 0.1, function () {
                _this["tipWindow"].hide();
            });
        }
    },
    /**
     * 打开请求远程页面窗口
     * **/
    openPageWindow: function (args, params, onDragStopFn) {
        this.openWindow(args, params, onDragStopFn, 'pageWindow');
        this.closeRemoveDom = true;
    },
    /**打开窗口
     * 可以在打开窗口时候注册 this.onWindowClosed 关闭回调，
     * this.onWindowClosed是临时性的，一旦调用后 即被设置为undefined
     * args ={
     *    title: ,
     *    width: ,
     *    height: ,
     *    contentFn:内容创建fn  
     * }
     * **/
    openWindow: function (args, params, onDragStopFn, windowName) {
        this.closeRemoveDom = false;
        var _this = this;
        if (typeof onDragStopFn === "function") {
            _this["onWidDragStopFn"] = onDragStopFn;
        } else {
            _this["onWidDragStopFn"] = undefined;
        }
        var winName = "window";
        if (typeof windowName !== "undefined") {
            winName = windowName;
        }
        this.windowName = winName;
        if (!this[winName]) {
            this[winName] = $("<div style='z-index:2147483647;' class='k_edit_window k_box_size k_box_shadow'><div tabindex='0' class='k_edit_window_header k_box_size'><span class='k_edit_window_label'></span><a tabindex='0'><i class='fa fa-cancel-2' tabindex='0'></i></a></div><div  class='k_edit_window_body k_box_size'><iframe class='current_window_ifr' frameborder='0' width='100%' height='100%' scrolling='no'></iframe></div></div>");
            this[winName].appendTo(_getBody());
            this[winName + "_iframe"] = this[winName].children(".k_edit_window_body").children("iframe");
            var ifr = this[winName + "_iframe"][0];
            var doc = ifr.contentWindow.document || ifr.contentDocument;           
            var linkArr = getCssloadString(this.flowScriptSrcs);            
            doc.open().write(linkArr);
            doc.close();
            this[winName + "_doc"] = doc;
            this[winName + "_body"] = $(doc.body).css({
                "margin": 0,
                "padding": 4
            });
            var header = this[winName].children(".k_edit_window_header");
            header.children("a").click(function () {
                _this.closeWindow();
                _getBody().css("cursor", "default");               
                return false;
            });
            this[winName].draggable({
                onDragReady: function () {
                    var picker = _this[winName].data("colorPicker");
                    if (picker) {
                        picker.hide();
                    }
                    return true;
                },
                onStopDrag: function (args) {
                    if (_this["onWidDragStopFn"]) {
                        _this["onWidDragStopFn"](args);
                    }
                },
                notClearRange: true,
            });
            this[winName + "_body"].click(function () {
                var picker = _this[winName].data("colorPicker");
                if (picker) {
                    picker.hide();
                }
            });
            var onFocus = function () {
                _this.rebuildUserRange();
                return false;
            };
            var bindFocus = function (ele) {
                ele.on("focus", onFocus);
                ele.children().each(function () {
                    bindFocus($(this));
                });
            };
            bindFocus(header);
            this.windowArray.push(this[winName]);//用于销毁
        }
        if (!this.mask) {
            this.mask = $("<div style='z-index:5' class='k_model_mask'></div>").appendTo(this.jqObj);
        }
        this[winName].children(".k_edit_window_header").find(".k_edit_window_label").html(args.title);
        this.closeTIPWindow();
        this._closeCxtMenu();
        var ofs = this.jqObj.offset();
        var top = ofs.top + (this.jqObj.outerHeight() / 2) - args.height / 2;
        var left = ofs.left + (this.jqObj.outerWidth() / 2) - args.width / 2;
        if(top < 0){
            top = 1;
        }       
        this[winName].css({
            width: args.width,
            height: args.height,
            top: top,
            left: left
        }).fadeTo(200, 1, function () {
            _this.mask.show();
        });
        if(winName !== "flowDesignWindow"){
            this[winName + "_body"].children().detach();
        }       
        args.contentFn(this[winName + "_body"], params, this[winName + "_doc"]);
    },
    /**关闭打开的
     * 关闭窗口
     * **/
    closeWindow: function () {
        if (window["_codeCssObject_"]) {
            window["_codeCssObject_"].removeTargets();
        }
        var wName = this.windowName;
        if (this[wName]) {
            var _this = this;
            var colorPicker = _this[wName].data("colorPicker");
            if (colorPicker) {
                colorPicker.opts.change = undefined;
            }
            this[wName].fadeTo(300, 0.1, function () {
                var w = $(this).hide();
                if (_this.closeRemoveDom || w.data("rmDom") ) {
                    w.remove();
                    _this[wName] = undefined;
                    _this[wName + "_iframe"] = undefined;
                    _this[wName + "_body"] = undefined;
                    _this[wName + "_doc"] = undefined;
                }
                _this.mask.hide();
            });
            _getBody().css("cursor", "default");
            if (this.closedSections && this.closedSections.length > 0) {
                for (var i = 0, len = this.closedSections.length; i < len; ++i) {
                    this.closedSections[i].removeClass("k_editor_closed_section");
                }
            }
            this.closedSections = [];
            this.removeSectionResizeBar();
            setTimeout(function(){
                if(_this.onWindowClosed){
                    _this.onWindowClosed();
                    _this.onWindowClosed = undefined;
                }
            },100);            
        }
        this.flowUpdateImg = undefined;//清理打开流程编辑设置的更新对象
    },
    /**获取光标所在的段落div**/
    getAnchorSectionEl: function () {
        var anchor = this.getAnchorJqNode();
        while (anchor.length > 0) {
            if (anchor[0].tagName === "DIV") {
                break;
            }
            anchor = anchor.parent();
        }
        return anchor;
    },
    /**
    * 显示右键菜单
    * ofs:位置
    * hideItems = [] 需要隐藏的项目
    * **/
    showMouseMenu: function (ofs, hideItems) {
        var diff = _getBody().height() - ofs.top;
        if (diff < 135) {
            ofs.top = ofs.top - 155;
        }
        diff = _getBody().width() - ofs.left;
        if (diff < 110) {
            ofs.left = ofs.left - 110;
        }
        var _this = this;
        var i, len;
        if (!this["mousemenu"]) {
            this["mousemenu"] = $('<div class="k_edit_input_ctxmenu k_box_shadow" style="width:auto;position:absolute;z-index:99999999;display:none;background:#ffffff;border:1px solid #E0E0E0;"></div>').appendTo(_getBody());
            var _focusFn = function () {
                _this.rebuildUserRange();
                return false;
            };
            var _clickFn = function () {
                var $t = $(this);
                var _handler = $t.data("handler");
                var _params = $t.data("params");
                setTimeout(function () {
                    _this.hideMouseMenu();
                }, 100);
                _this.execute(_handler, _params);
            };
            for (i = 0, len = config.mouseMenu.length; i < len; ++i) {
                var it = config.mouseMenu[i];
                var icon = it.icon,
                    title = it.title,
                    handler = it.handler,
                    params = it.params;
                var $it = $("<div tabindex='0' class='_" + handler + "'><i style='padding-right:4px;' class='fa " + icon + "'></i><span>" + title + "</span></div>").appendTo(this["mousemenu"])
                    .focus(_focusFn).click(_clickFn).data("handler", handler).data("params", params);
                $it.children().focus(_focusFn);
                if (it.tip) {
                    $it.attr("title", it.tip);
                }
            }
            this["mousemenu"].mousedown(function () {
                stopDefaultctxMenu();
            });
        }
        this["mousemenu"].children().show();        
        if (hideItems && hideItems instanceof Array) {
            for (i = 0, len = hideItems.length; i < len; ++i) {
                this["mousemenu"].children("._" + hideItems[i]).hide();
            }
        }
        for(i = 0, len = this.defaultHideMouseIts.length; i < len; ++i){
            this["mousemenu"].children("._" + this.defaultHideMouseIts[i]).hide();
        }

        var $p = this.getAnchorSectionEl();
        var closed_count = $p.attr("closed_count");
        var $n = this["mousemenu"].find("._closedNext");
        if (closed_count) {
            $n.children("span").text(eConfig.label.cancelNext);
        } else {
            $n.children("span").text(eConfig.label.closedNext);
        }
        var style = this._style2CssObject($p);
        if (style.width && style.width !== "auto") {
            this["mousemenu"].find("._resetSectionWidth").show();
        } else {
            this["mousemenu"].find("._resetSectionWidth").hide();
        }
        this["mousemenu"].css(ofs).show();
    },
    /***隐藏鼠标菜单***/
    hideMouseMenu: function () {
        if (this["mousemenu"]) {
            this["mousemenu"].hide();
        }
    },
    /***移除段落宽度设置拖动条***/
    removeSectionResizeBar: function () {
        if (this.sectionResizeBar) {
            this.sectionResizeBar.remove();
            this.sectionResizeBar = undefined;
        }
        if (this.sectionResizeBar2) {
            this.sectionResizeBar2.remove();
            this.sectionResizeBar2 = undefined;
        }
        if (this.resizePelement) {
            for (var i = 0, len = this.resizePelement.length; i < len; ++i) {
                this.resizePelement[i].removeClass("k_editor_closed_section");
            }
            this.resizePelement = undefined;
        }
    },        
    /**关闭所有显示的窗口**/
    closeAllWindow: function () {
        this.closeTIPWindow();
        this.hideMouseMenu();
        if (this["resizeBox"]) {
            this["resizeBox"].unbind();
        }
    },
    /***初始化输入框事件
     * ***/
    _initInputEvents: function ($input) {
        var _this = this;
        var reSaveRange = false;
        var isClosed = false;
        var clearColosedTimer;
        var clearRangeTimer;           
        var inputMouseUpEnvent = function(e){
            _this.go2docListner = false;
            var clearClickObject = true;
            var parent = e.target;
            var nodeName;
            while (parent) {
                nodeName = parent.nodeName;
                if (nodeName === "DIV") {
                    break;
                }
                if (nodeName === "TD") {
                    clearClickObject = false;
                    break;
                }
                parent = parent.parentNode;
            }
            if (clearClickObject) {
                _this.clickActivedObject = undefined;
            }
            if (_this.clickActivedDomObject) { //当前点击的是一个dom-jq对象
                _this.clickActivedDomObject.removeClass("k_edit_actived_object");
                _this.clickActivedDomObject = undefined;
            }
            //是否是格式刷操作
            if (_this.brushCss) {
                _this.brush2Target();
            }
           
            setTimeout(function () {              
                _this.saveUserRange();                
                if (reSaveRange) {
                    //_this.saveUserRange();
                    if (e.which === 3 && e.target.nodeName !== "A") {
                        var hideItems = ['editLink', 'unlink'];
                        parent = $(parent);
                        var showClosed = false;
                        if (nodeName === "DIV") {
                            showClosed = _this.getDomRange().collapsed;
                            if (showClosed) {
                                var elLen = parent.width();
                                var chLen = 0;
                                parent.children().each(function () {
                                    chLen = chLen + $(this).width();
                                });
                                if (chLen < elLen) {
                                    showClosed = true;
                                }
                            }
                        }
                        showClosed = _this.getAnchorSectionEl().next("._section_div_").length > 0;
                        if (!showClosed) {
                            hideItems.push("closedNext");
                        }
                        //浮动文本框 需要隐藏的项目
                        if (_this.$input.hasClass("k_editor_float_input")) {
                            hideItems.push('showInsertImageWindow');
                            hideItems.push('setSectionMove');
                        }
                        _this.showMouseMenu({
                            top: e.pageY,
                            left: e.pageX
                        }, hideItems);
                    }
                }
                reSaveRange = false;
                //工具栏联动
                if (_this.tools && typeof _this.tools.clickSubscribe === "function") {
                    var rangeCss = _this._getRangeCss(false,false,true);
                    _this.tools.clickSubscribe(_this, rangeCss);
                }
                var eventNode = e.target;
                var isTdEle = eventNode.nodeName === "TD";
                while (eventNode.nodeName !== "DIV" && !isTdEle) {
                    eventNode = eventNode.parentNode;
                    if (!eventNode) {
                        break;
                    }
                    isTdEle = eventNode.nodeName === "TD";
                    if (eventNode.nodeName === "LI") {
                        break;
                    }
                }
                if (!isTdEle) { //避免取消当前点击的单元格
                    for (var i = 0, len = _this.tables.length; i < len; i++) {
                        if (typeof _this.tables[i].clickSubscribe === "function") {
                            _this.tables[i].clickSubscribe(_this);
                        }
                    }
                }
            }, 50);
        };
        if($input.hasClass("k_edit_input_filed")){
            //注册dom mouseup 解决划选时候，鼠标在input区域外无法触发inputMouseUpEnvent的场景
            var $doc = $(window.document);
            var event = 'mouseup.'+this.id;
            $doc.off(event);
            $doc.on(event , function(e){
                if(_this.go2docListner){
                    //console.log("go2docListner mouseup.paintBrushlistener");
                    _this.go2docListner = false;
                    inputMouseUpEnvent(_this.mouseDownArgs);
                } 
                _this.mouseDownArgs = undefined;              
            });
        }
        window["_b_u_i___"]= true;
        //应该加入双击全选功能
        $input.on("mousedown", function (e) {  
            if( _this.imgMask){
                _this.imgMask.remove();
                _this.imgMask = undefined;
            }
           // console.log("input mouse down event!"); 
           if(e.which === 3){
                stopDefaultctxMenu(); 
           }                         
            if (_this.movingAcn && !_this.movingScroll) {
                _this.movingAcn.hide();
            }
            _this.removeSectionResizeBar();
            _this.closeAllWindow();
            var $i = $(this);
            _this.$input = $i;
            var isFloatInput = $i.hasClass("k_editor_float_input");
            if (isFloatInput) {//浮动文本输入
                _this.disabledFunc(eConfig.floatEidtor);
            } else {
                _this.enabledFunc();//启用按钮
                if (_this.floatTools) {
                    _this.floatTools.hide();
                }
            }            
            reSaveRange = true;
            _this._clearRangeRecord();
            _this.go2docListner = true;
            _this.mouseDownArgs = e;

        }).on("keyup", function (e) {
            if (_this.isPasting) {
                return false;
            }
            //回车 需要处理空br、li内回车、td内回车的问题！
            var isDeleted = e.keyCode === 8 || e.keyCode === 46;
            //console.log(" e.keyCode  = "+e.keyCode);
            var domRange = _this._getDomRangeOnly();
            var commonAncestorContainer = domRange.commonAncestorContainer;
            if(e.keyCode === 39){
                if (commonAncestorContainer.nodeType === 1 && commonAncestorContainer.nodeName === "SPAN") {
                    var  $c = $(commonAncestorContainer);
                    if($c.children("img").length > 0){
                        if($c.next("span").length === 0 ){
                           var newspan = _this._getSpan().insertAfter($c);
                           _this.moveToEnd(newspan);
                        } 
                    }
                }
            }
            if (isDeleted) {
                if (commonAncestorContainer.nodeType === 1 && commonAncestorContainer.nodeName === "DIV") {
                    var s1 = $(commonAncestorContainer);
                    var preS1 = s1.prev();
                    if (preS1.length > 0) {
                        s1.remove();
                        _this.moveToEnd(preS1);
                    }
                }
                //处理删除后的处理，检查table是否还存在,处理顺序列表问题
                _this.onDeleteKeyup(e.keyCode);
            }
            var isCode = false;
            var node = _this.getAnchorJqNode();
            var isLi = false,
                liTag,
                isTd = false,
                tagName,
                parentNode;
            if (node[0].tagName === "PRE") {
                isCode = true;
            }
            //检测是否是列表li里的回车
            if (node[0].tagName !== "DIV") {
                parentNode = node.parent(); //parentNode递归到段落div 
            } else {
                parentNode = node;
            }
            var $pre, $pElement;
            while (parentNode.length > 0) {
                tagName = parentNode[0].tagName;
                if (tagName === "DIV") {
                    break;
                }
                if (tagName === "LI") {
                    isLi = true;
                    liTag = parentNode;
                }
                if (tagName === "TD") {
                    isTd = true;
                }
                if (tagName === "P") {
                    $pElement = parentNode;
                }
                if (tagName === "PRE") {
                    $pre = parentNode;
                    isCode = true;
                }
                parentNode = parentNode.parent();
            }
            if (isCode) {
                if ($pre) {//pre元素内回车
                    $pre.remove();
                    var newPel = _this.createPElement();
                    newPel.insertAfter(parentNode);
                    _this.moveToEnd(newPel);
                }
                return false;
            }
            if (e.keyCode === 13) {                
                var updateTag = parentNode;
                if (isTd) {
                    updateTag = $pElement;
                } else if (isLi) {
                    updateTag = liTag;
                } else { }
                /***继承上一行高***/
                var prevEl = updateTag.prev();
                var lineHeight = prevEl.css("line-height");
                var paddingLeft = prevEl.css("padding-left");
                //var maxFs = _this._getParagraphMaxFontSize(updateTag);
                updateTag.css({ "line-height": lineHeight, "padding-left": paddingLeft });
                //段落回车自动序号支持
                var isPel = prevEl[0].tagName === "DIV" || prevEl[0].tagName === "P";
                if (isPel) {
                    _this._autoSeq(updateTag, prevEl);
                    _this.moveToEnd(updateTag);//回车后确保输入焦点不在序列span
                }
                var currentId = updateTag.attr("id");
                _this._updateId(updateTag);
                _this.clearUserRange();
                if (updateTag.text() === "\u200B") {
                    _this.moveToEnd(updateTag);
                }
                if (!isLi && !isTd) {
                    _this["undoRedoRec"].replaceSectionId.push(parentNode.attr("id"));
                }
                _this._putUndo();
                //段落绑定事件
                updateTag.bind("mouseenter", { "_this": _this }, _this.bindSectionElEvent);
                //修正id
                while(prevEl.length > 0){
                    if(prevEl.attr("id") === currentId){
                        _this._updateId(prevEl);
                        prevEl = prevEl.prev();
                    }else{
                        break;
                    }
                }
            } else {
                //预防在span标签中存在文字和子标签                   
                var range = _this.getDomRange(false);
                if (range) {
                    var pNode, newSpan;
                    var ancContainer = range.commonAncestorContainer;
                    if (ancContainer.nodeType === 3) {
                        var val = ancContainer.nodeValue;
                        pNode = ancContainer.parentNode;
                        if (val !== "" && pNode.tagName !== "TD") {
                            if (ancContainer.nextSibling) {
                                pNode.removeChild(ancContainer);
                                newSpan = _this._getSpan().html(val).insertBefore($(pNode));
                                _this.moveToEnd(newSpan);
                            } else if (ancContainer.previousSibling) {
                                pNode.removeChild(ancContainer);
                                newSpan = _this._getSpan().html(val).insertAfter($(pNode));
                                _this.moveToEnd(newSpan);
                            }
                        }
                    }
                    if (e.keyCode === 9) { //tab键
                        range = _this.getDomRange(false);
                        ancContainer = range.commonAncestorContainer;
                        var startOffset = range.startOffset,
                            endOffset = range.endOffset;
                        if (startOffset === endOffset) {
                            var nodeValue = ancContainer.nodeValue;
                            pNode = $(ancContainer.parentNode);
                            var arr = [], v;
                            var newStart = startOffset;
                            if (nodeValue === "\u200b") {
                                arr.push("\u200b");
                                arr.push("&nbsp;&nbsp;&nbsp;&nbsp;");
                                newStart = newStart + 4;
                            } else {
                                for (var i = 0, len = nodeValue.length; i < len; ++i) {
                                    if (startOffset === 0 && i === 0) {
                                        arr.push("&nbsp;&nbsp;&nbsp;&nbsp;");
                                        newStart = newStart + 4;
                                    }
                                    v = nodeValue[i];
                                    if (v === "\u200b") {
                                        v = "\u200b";
                                    }
                                    arr.push(v);
                                    if (i === (startOffset - 1)) {
                                        arr.push("&nbsp;&nbsp;&nbsp;&nbsp;");
                                        newStart = newStart + 4;
                                    }
                                }
                            }
                            nodeValue = arr.join("");
                            pNode.html(nodeValue);
                            var el = pNode[0].firstChild;
                            _this.setCrossRange(el, el, newStart, newStart);
                        }
                    }
                }
                clearTimeout(_this["saveUserRangeTimer"]);
                _this["saveUserRangeTimer"] = setTimeout(function () {
                    _this.saveUserRange();
                }, 500);
            }
        });
        $input.parent().on("scroll", function () {
            if (_this.movingAcn && !_this.movingScroll) {
                _this.movingAcn.hide();
            }
            if (_this.resizing) {
                return true;
            }
            if (!isClosed) {
                _this.closeAllWindow();
                isClosed = true;
                for (var j = 0, jlen = _this.tables.length; j < jlen; ++j) {
                    _this.tables[j].hideMenu();
                }
            }
            if(_this.floatTools){
                _this.floatTools.onScroll();
            }
            clearTimeout(clearColosedTimer);
            clearColosedTimer = setTimeout(function () {
                isClosed = false;
            }, 1000);
        });       
        // 跨行删除的撤销重做问题
        // 回车换行撤销 重做有问题
        $input.on("keydown", function (e) {
            _this.closeAllWindow();
            var code = e.keyCode;
            var txt;
            if (e.keyCode === 13) { //回车
                _this._onChange();
                _this.saveUserRange();
                _this._makeUndoDataByFocus();
            } else if (code === 8 || code === 46) { //删除操作
                _this._onChange();
                var range = _this.range;
                _this["isSelectedContent"] = !range.collapsed;
                var anchorNode = range.commonAncestorContainer;
                var node;
                if (anchorNode["nodeType"] === 3) {
                    node = $(anchorNode.parentNode);
                } else {
                    node = $(anchorNode);
                }
                //最后一个段落div不能被删除
                if (!node.hasClass("k_edit_input_filed") && node.hasClass("_section_div_")) {
                    txt = node.text();
                    if (node.siblings().length === 0) {
                        if (txt === "" || txt === "\u200B") {
                            return false;
                        }
                    }
                }
                while (node.length > 0) {
                    if (node.hasClass("_section_div_") || node.hasClass("k_edit_input_wrap") || node.hasClass("k_editor_float_input")) {
                        break;
                    }
                    node = node.parent();
                }
                txt = node.text();
                _this.isEmptySection = txt === "" || txt === "\u200B";
                if (_this.isEmptySection && node.siblings().length === 0) { // 
                    return false;
                }
                //创建undo栈的记录数据并入栈
                _this._makeUndoDataByFocus();
                _this._putUndoDelayed();
            }
        });

        /***避免选择时候，鼠标移出编辑区域的情况***/
        $input.on("mouseup", inputMouseUpEnvent).on("mouseleave", function () { //应该采用mouseout，避免
            setTimeout(function () {
                if (reSaveRange) {
                    _this.saveUserRange();
                }
                reSaveRange = false;
            }, 200);
        });
        $input.on("paste", { _this: this }, _this.onPaste);
    }, /**段落回车自动序号支持
    * 支持序列格式 : 1. 2. | 1、2、| 一. 二. | 一、 二 、
    * ***/
    _autoSeq: function (updateTag, prevEl) {
        var _this = this;
        var seqRes = _this._getSectionSeqDatas(prevEl);
        if (seqRes.isSeq) {
            //分析提取回车行序列
            var seqEl = seqRes.seqEl;
            var seqSpanEl = seqEl;
            var nodeText = seqRes.nodeText;
            var seqNum = seqRes.seqNum;// 
            var seqNumTxt = seqRes.seqNumTxt;
            seqEl.html(nodeText.replace(seqNumTxt, ""));
            var cssStyle = _this._getCopyStyle(seqEl);
            var newSpan = _this._getSpan().css(cssStyle);
            //将序列前面的空元素内容合并到newSpan中，并删除空元素
            for (var i = 0, len = seqRes.emptyEl.length; i < len; ++i) {
                var rmEl = seqRes.emptyEl[i];
                var html = rmEl.html();
                seqNumTxt = html + seqNumTxt;
                rmEl.remove();
            }
            seqNumTxt = "\u200B" + seqNumTxt;
            newSpan.html(seqNumTxt).insertBefore(seqEl);
            //生成新行序列    
            var nextSeq, nextSeqText, nextChseq, chSeqIndex;
            if (seqRes.isChSeq) {
                nextChseq = getChNextSeq(seqNum);
                nextSeq = nextChseq.seq;
                nextSeqText = seqNumTxt.replace(seqNum, nextSeq);
                chSeqIndex = nextChseq.index;
            } else {
                nextSeq = seqNum + 1;
                nextSeqText = seqNumTxt.replace(/\d+/g, nextSeq);
            }
            var nextpan = _this._getSpan().css(cssStyle);
            nextpan.html(nextSeqText);
            updateTag.prepend(nextpan);
            var acnSpan = nextpan.next();
            if (acnSpan.length > 0) {
                this.moveToStart(acnSpan);
            }
            var nextPelement = updateTag.next("._section_div_");
            var count = 0;
            while (nextPelement.length > 0) {//更新后面的序列排序                   
                seqRes = _this._getSectionSeqDatas(nextPelement);
                if (seqRes.isSeq) {
                    seqEl = seqRes.seqEl;
                    if (_this._isSameSeq(seqNumTxt, seqRes.seqNumTxt, seqSpanEl, seqEl)) {
                        count = 0;
                        if (seqRes.isChSeq) {
                            chSeqIndex++;
                            nextSeq = chSeqArray[chSeqIndex];
                            nextSeqText = seqRes.seqNumTxt.replace(seqRes.seqNum, nextSeq);
                            seqEl.html(nextSeqText);
                        } else {
                            nextSeq++;
                            nextSeqText = seqRes.seqNumTxt.replace(/\d+/g, nextSeq);
                            seqEl.html(nextSeqText);
                        }
                        if (seqRes.nodeText !== seqRes.seqNumTxt) {//需要补充一个span内容
                            seqRes.nodeText = seqRes.nodeText.replace(seqRes.seqNumTxt, "");
                            _this._getSpan().html(seqRes.nodeText).insertAfter(seqEl);
                        }
                    } else {
                        break;
                    }
                } else {
                    count++;
                    if (count > 5) {
                        break;
                    }
                }
                nextPelement = nextPelement.next("._section_div_");
            }
        }
    },
    /**复制 粘贴处理**/
    onPaste: function (e) {
        var _this = e.data._this;
        _this._makeUndoDataByFocus(true);//记录撤销
        _this._putUndo();
        _this._onChange();
        _this.isPasting = true;
        clearTimeout(_this.isPastingTimer);
        _this.isPastingTimer = setTimeout(function () {
            _this.isPasting = false;
        }, 1000);
        var range = _this.getDomRange();
        var isCollapsed = range.collapsed;
        if (!isCollapsed) {//跨选区不支持
            return false;
        }
        var startOffset = range.startOffset;
        var commonAncestorContainer = range.commonAncestorContainer;
        var nodeValue = commonAncestorContainer.nodeValue;
        var isEmpty = nodeValue === "" || nodeValue === "\u200B";
        var pasteHtml, docSplitHtml;
        var data = e.clipboardData || e.originalEvent.clipboardData;
        var ieData = window.clipboardData;
        var isPureText = false;
        //console.log("paste data >>>>> ");
        // 粘贴过滤了样式的、只有标签的 html
        if (data && data.getData) {
            pasteHtml = data.getData('text/html');
            docSplitHtml = pasteHtml.split('</html>');
            if (docSplitHtml.length === 2) {
                pasteHtml = docSplitHtml[0];
            }
            if (pasteHtml) {
                var bodyStartIndex = pasteHtml.search(/(<body>)|(<body\s+\S+[^>]+>)/gi);
                var bodyStart = pasteHtml.match(/(<body>)|(<body\s+\S+[^>]+>)/gi);
                var bodyEndIndex = pasteHtml.search(/(<\/body>)/gi);
                pasteHtml = pasteHtml.substring(bodyStartIndex + bodyStart[0].length, bodyEndIndex);
                pasteHtml = pasteHtml.replace("<!--StartFragment-->", "").replace("<!--EndFragment-->", "");
                //pasteHtml.replace(/</g, '&lt;').replace(/>/g, '&gt;');
            } else {
                isPureText = true;
                pasteHtml = data.getData('text/plain');
                if (pasteHtml) {
                    pasteHtml = pasteHtml.replace(/[ ]/g, '&nbsp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
                }
            }
        } else if (ieData && ieData.getData) {
            // IE 直接从剪切板中取出纯文本格式
            pasteHtml = ieData.getData('text');
            isPureText = true;
        }
        var newVals = [], i, len;
        var move2end = true;
        var anchor = _this.getAnchorJqNode();
        var fun = function (content) {
            var add2end = true;
            for (var j = 0, jlen = nodeValue.length; j < jlen; ++j) {
                if (j === startOffset) {
                    newVals.push(content);
                    add2end = false;
                }
                newVals.push(nodeValue[j]);
            }
            if (add2end) {
                newVals.push(content);
            }
            startOffset = startOffset + content.length;
            anchor.html(newVals.join(""));
            var ele = anchor[0].firstChild;
            _this.setCrossRange(ele, ele, startOffset, startOffset);
            move2end = false;
        };
        if (pasteHtml) {
            console.log("paste >>>>>");
            if (isPureText) {//纯文本复制
                pasteHtml = pasteHtml.replace(/\n\r?/g, "");
                if (isEmpty) {
                    anchor.html(pasteHtml);
                    _this.moveToEnd(anchor);
                } else {
                    fun(pasteHtml);
                }
            } else {//复杂内容复制
                //resArray 要确保都是div级别的元素
                var resArray = _this.formatPasteData(pasteHtml);
                var $pel = anchor.parent();
                var isP = false;
                if ($pel[0].tagName === "DIV") {
                    isP = true;
                }
                var _ctx = $pel.text();
                var isEmptyp = _ctx === "" || _ctx === "\u200B";
                var currentNewPel;                
                for (i = 0, len = resArray.length; i < len; ++i) {
                    move2end = true;
                    var $c = $(resArray[i]);//$c 一定是div级别的元素
                    var $tab = $c.children("table");
                    if($tab.length > 0){
                        $tab.siblings().remove();
                    }
                    if (isP) {
                        if (i === 0) {
                            if (isEmptyp) {
                                if ($c[0].tagName === "OL" || $c[0].tagName === "UL") {
                                    $pel.html("");
                                    currentNewPel = $pel.append($c);
                                } else {
                                    if($tab.length > 0){
                                        $pel.children().remove();
                                    }
                                    currentNewPel = $pel.append($c.children().remove());
                                }
                            } else {
                                var newText = $c.text();
                                if (isEmpty) {
                                    anchor.html(newText);
                                } else {
                                    fun(newText);
                                }
                                currentNewPel = $pel;
                            }
                        } else {
                            currentNewPel = $c.insertAfter(currentNewPel);
                            //绑定div事件
                            $c.bind("mouseenter", { "_this": _this }, _this.bindSectionElEvent);  
                        }
                        _this._fixNestSpan(currentNewPel);  //清除嵌套span
                        _this.buildObjectsEventsByTag(currentNewPel);//绑定复制里面的table 链接事件
                    } else {//li 单元格内复制
                        var tmpTxt = [];
                        for (var k = 0, klen = resArray.length; k < klen; ++k) {
                            tmpTxt.push($(resArray[k]).text());
                        }
                        if (isEmpty) {
                            anchor.append(tmpTxt.join(""));
                        } else {
                            fun(tmpTxt.join(""));
                        }
                        break;
                    }
                }
                if (isP) {
                    if (currentNewPel.next().length === 0) {
                        var newPel = _this.createPElement().insertAfter(currentNewPel);
                        if(currentNewPel.children("table").length > 0){
                            currentNewPel = newPel;
                        }
                    }
                    if (move2end) {
                        _this.moveToEnd(currentNewPel);
                    }                  
                } else if (move2end) {
                    _this.moveToEnd(anchor);
                }
            }
        }
        return false;
    },
    /***
     * 插入表情、图标，行内图片时候，获取待插入的span
     * ***/
    _getInsertSpan:function(){
        var range = this.range;
        if (range) {
            var endContainer = range.endContainer;
            var endOffset = range.endOffset;
            var nodeValue = endContainer.nodeValue;
            var wrap = $(endContainer.parentNode);
            var copyStyle,targetSapn;
            if (nodeValue !== "" && nodeValue !== "\u200B") {
                var res = $(this._text2spanWrap(nodeValue, 0, endOffset, false));
                res.insertAfter(wrap);
                copyStyle = this._getCopyStyle(wrap);
                wrap.remove();
                var target;
                res.each(function () {
                    var $t = $(this);
                    if ($t.hasClass("_wrap_target_node_")) {
                        target = $t.removeClass("_wrap_target_node_");
                    }
                }).css(copyStyle);
                targetSapn = target;
            } else {
                targetSapn = wrap;
            }
            return targetSapn;
        }        
    },
    /**
     * 将复制的数据格式化为富文本格式的数据
     * **/
    formatPasteData: function (data) {
        var i, len, j, jlen, tmpArr, $c, $span, s;
        var res = [];
        //换行分割
        if(data.indexOf("<") >= 0 && data.indexOf("</") >= 0){ //如果是符合标签元素
            data = data.replace(/\r?\n\r?/g,"");
        }        
        var sections = data.split(/\n\r?/);
        len = sections.length;
        for (i = 0; i < len; ++i) {
            s = $.trim(sections[i]);
            if (s !== "") {
                tmpArr = this._pasteClear(s);
                for (j = 0, jlen = tmpArr.length; j < jlen; ++j) {
                    $c = $(tmpArr[j]);
                    if ($c[0].tagName === "DIV" && $c.children().length === 0) {
                        $span = this._getSpan().text($c.text());
                        $c.html($span[0].outerHTML);
                    }
                    res.push($c);
                }
            }
        }
        //应该确保res数组元素是段落div级别的  
        len = res.length;
        var setArr = [];
        var tmp, newSection;
        for (i = 0; i < len; ++i) {
            tmp = res[i];
            if (tmp[0].tagName !== "DIV") {
                if (!newSection) {
                    newSection = this.createPElement();
                    setArr.push(newSection);
                }
                if(tmp[0].tagName === "TABLE"){
                    newSection.children().remove();
                }
                newSection.append(tmp);
            } else {
                setArr.push(tmp);
                newSection = undefined;
            }
        }
        return setArr;
    },
    _onPasteReplace:function(html,replaceTable){
        html = html.replace(/<\/?IMG[^>]*>/gi, "");
        //html = html.replace(/<\/?TABLE[^>]*>/gi, ""); 保留表格复制
        //html = html.replace(/<\/?style[^>]*>/gi, "");
        html = html.replace(/<(\w[^>]*) class=([^ |>]*)([^>]*)/gi, "<$1$3");
        //html = html.replace(/<(\w[^>]*) style="([^"]*)"([^>]*)/gi, "<$1$3") ;
        // Remove Lang attributes
        html = html.replace(/<(\w[^>]*) lang=([^ |>]*)([^>]*)/gi, "<$1$3");
        html = html.replace(/<\\?\?xml[^>]*>/gi, "");
        html = html.replace(/<\/?\w+:[^>]*>/gi, "");
        html = html.replace(/ /, " ");
        html = html.replace(/(<b>)|(<b\s+.*?>)/gi, "<span id='" + getUUID() + "' style='font-weight:bold;'>");
        html = html.replace(/(<\/b>)/gi, "</span>");
        html = html.replace(/(<i>)|(<i\s+.*?>)/gi, "<span  id='" + getUUID() + "' style='font-style: italic;'>");
        html = html.replace(/(<\/i>)/gi, "</span>");
        html = html.replace(/(<u>)|(<u\s+.*?>)/gi, "<span  id='" + getUUID() + "' style='text-decoration:underline;'>");
        html = html.replace(/(<\/u>)/gi, "</span>");
        html = html.replace(/(<strike>)|(<strike\s+.*?>)/gi, "<span  id='" + getUUID() + "' style='text-decoration:line-through;'>");
        html = html.replace(/(<\/strike>)/gi, "</span>");

        var re = new RegExp("(<P)([^>]*>.*?)(<\/P>)", "gi");
        html = html.replace(re, "<div   $2</div>");
        re = new RegExp("(<H1)([^>]*>.*?)(<\/H1>)", "gi");
        html = html.replace(re, "<div   $2</div>");
        re = new RegExp("(<H2)([^>]*>.*?)(<\/H2>)", "gi");
        html = html.replace(re, "<div   $2</div>");
        re = new RegExp("(<H3)([^>]*>.*?)(<\/H3>)", "gi");
        html = html.replace(re, "<div   $2</div>");
        re = new RegExp("(<H4)([^>]*>.*?)(<\/H4>)", "gi");
        html = html.replace(re, "<div   $2</div>");
        re = new RegExp("(<H5)([^>]*>.*?)(<\/H5>)", "gi");
        html = html.replace(re, "<div   $2</div>");
        re = new RegExp("(<H6)([^>]*>.*?)(<\/H6>)", "gi");
        html = html.replace(re, "<div   $2</div>");
        // 剔除span,div ,table tr td 之外的元素            
        html = html.replace(/<.*?>/ig, function (tag) {
            tag = tag.toLowerCase();
            var isTableTag = false;
            if(replaceTable){
                isTableTag = tag.indexOf('</tr>') === 0 || tag.indexOf('<tr ') === 0 || tag.indexOf('<tr>') === 0 ||
                tag.indexOf('</td>') === 0 || tag.indexOf('<td ') === 0 || tag.indexOf('<td>') === 0 ||
                tag.indexOf('</table>') === 0 || tag.indexOf('<table ') === 0 || tag.indexOf('<table>')  === 0 ;
            }            
            if (tag.indexOf('</span>') === 0 || tag.indexOf('<span ') === 0 || tag.indexOf('<span>') === 0 ||
                tag.indexOf('</div>') === 0 || tag.indexOf('<div ') === 0 || tag.indexOf('<div>') === 0 ||
                tag.indexOf('</ol>') === 0 || tag.indexOf('<ol ') === 0 || tag.indexOf('<ol>') === 0 ||
                tag.indexOf('</ul>') === 0 || tag.indexOf('<ul ') === 0 || tag.indexOf('<ul>') === 0 ||
                tag.indexOf('</li>') === 0 || tag.indexOf('<li ') === 0 || tag.indexOf('<li>') === 0 || isTableTag) {
                return tag;
            } else {
                return "";
            }
        });
        return html;
    },
    /**粘贴清理
     * 移除非法属性，非法标签
     * **/
    _pasteClear: function (htmlStr) {
        //console.log(htmlStr);
        var html = this._onPasteReplace(htmlStr,true);       
        var doms = $(html);
        var _this = this;
        var dom, i, len;
        var emptySpan = [];
        var eachChildFn = function () {
            var $el = $(this);
            //解除span里面的嵌套
            _this._removeNestSpan($el);
            _this._removeUnlegalAttr(this,true);
            $el.attr("id", getUUID());
            if ($el.text() === "") {
                emptySpan.push($el);
            }
        };
        var wrapFn = function () {
            if (this.nodeType === 3) {
                var spanHtml = _this._getSpan()[0].outerHTML;
                $(this).wrap(spanHtml);
            }
        };
        for (i = 0, len = doms.length; i < len; ++i) {
            dom = doms[i];
            var $dom = $(dom);
            _this._removeUnlegalAttr(dom);
            if ($dom[0].tagName === "DIV") {
                $dom.addClass("_section_div_");
            }else if($dom[0].tagName === "TABLE"){//clearTable
                _this._pasteTable($dom);
            }
            $dom.children().each(eachChildFn);
            if ($dom.children().length > 0) {
                $dom.contents().each(wrapFn);
            }
        }
        for (i = 0, len = emptySpan.length; i < len; ++i) {
            emptySpan[i].remove();
        }
        //确保div元素的子元素不存在div元素
        var delEles = [];
        doms.children().each(function () {
            var $d = $(this);
            if ($d[0].tagName === "DIV") {
                var $span = _this._getSpan().html($d.text());
                $span.insertAfter($d);
                delEles.push($d);
            }
        });
        for (i = 0, len = delEles.length; i < len; ++i) {
            delEles[i].remove();
        }
        //console.log(">>>>>>>>>>>>>>");
        return doms;
    },
    /**
     * 处理复制中的表格
     * ***/
    _pasteTable:function($tab){
        $tab.attr("id",getUUID()).addClass("k_box_size").css("border-collapse","collapse");
        var $tbody = $tab.children("tbody");
        var trs ;
        if($tbody.length > 0){
            $tbody.attr("id",getUUID());
            trs = $tbody.children();
        }else{
            trs = $tab.children("tr");
        }
        var _this = this;
        trs.each(function(i){
            var tr = $(this);
            tr.attr("id","row_"+i);
            //table 里面的 段落为 p元素
            tr.children().each(function(){
                var td  = $(this);
                var w = td.attr("width");                
                var html = td.html();//处理td内的html，
                var htmlStr = _this._onPasteReplace(html,true);  
                var re = new RegExp("(<div)([^>]*>.*?)(<\/div>)", "gi");
                htmlStr = htmlStr.replace(re, "<p   $2</p>");
                //console.log(htmlStr);
                td.html(htmlStr);
                if(w){
                    w = parseInt( w.replace("pt" , "px"));
                    td.width( w );
                }
                _this._removeUnlegalAttr(this,true);              
            });
        });
    },
    /***
     * 移除嵌套span
     * ***/
    _removeNestSpan: function ($el) {
        if ($el[0].tagName === "SPAN") {
            var text = $el.text();
            $el.children().remove();
            $el.text(text);
        } else {//
            var _this = this;
            var spanHtml = this._getSpan()[0].outerHTML;
            $el.contents().each(function () {
                if (this.nodeType === 3) {
                    $(this).wrap(spanHtml);
                }
            });
            $el.children().each(function () {
                _this._removeNestSpan($(this));
            });
        }
    },
    /**
     * 格式化样式 废弃用不到了！
     * recursion:是否递归处理
     * ***/
    _formatStyle: function ($el,recursion) {
        var style = $el.attr("style");
        $el.attr("id", getUUID());
        if (style) {
            var array = style.split(";");
            var newStyle = {};
            for (var i = 0, len = array.length; i < len; ++i) {
                var tmp = array[i].split(":");
                var name = $.trim(tmp[0]);
                var value = $.trim(tmp[1]);
                if (legalCssStyleNames.indexOf(name) >= 0) {
                    if (name === "font-family") {
                        if (value === 'Microsoft Yahei') {
                            value = '微软雅黑';
                        }
                        if (legalFontFamilys.indexOf(value) >= 0) {
                            newStyle[name] = value;
                        }
                    } else if (name === "font-size") {
                        if (value.indexOf("pt") > 0) {
                            value = value.replace(/\.[0]+pt/, "");
                            newStyle[name] = fontSizePt2Px[value];
                        } else {
                            newStyle[name] = value;
                        }
                    } else if (name === "font-weight") {
                        if (legalFontWeights.indexOf(value) >= 0) {
                            newStyle[name] = value;
                        }
                    } else if (name === "font-style") {
                        if (legalFontStyles.indexOf(value) >= 0) {
                            newStyle[name] = value;
                        }
                    } else if (name === "text-decoration") {
                        if (legalTextDecorations.indexOf(value) >= 0) {
                            newStyle[name] = value;
                        }
                    } else if (name === "text-align") {
                        if (legalTextAligns.indexOf(value) >= 0) {
                            newStyle[name] = value;
                        }
                    } else if (name === "background-color" || name === "color") {
                        newStyle[name] = value;
                    } else {
                        newStyle[name] = value;
                    }
                }
            }
            $el.removeAttr("style");
            $el.css(newStyle);
            if(recursion){
                var _this = this;
                $el.children().each(function(){
                    var child = $(this);
                    _this._formatStyle(child,recursion);
                });
            }
        }
    },
    /***
     * 剔除可能引起xss的关键词
     * ** */
    _unhtmlForUrl: function (str, reg) {
        return str ? str.replace(reg || /[<">']/g, function (a) {
            return {
                '<': '&lt;',
                '&': '&amp;',
                '"': '&quot;',
                '>': '&gt;',
                "'": '&#39;',
                "cookie": '',
                "eval": ''
            }[a];
        }) : '';
    },
    /***移除非法属性，并处理style属性值，确保在合法范围内，_formatStyle 可以不需要再调用
     * ,recursion 是否递归
     * ***/
    _removeUnlegalAttr: function (ele,recursion) {
        //console.log("_removeUnlegalAttr >>>>> recursion "+recursion);
        var attrs = ele.attributes || [];              
        ele.setAttribute("id" , getUUID());
        var _this = this;
        var nodeName = ele.nodeName;
        var isP = nodeName === "DIV" || nodeName === "P";
        var k ,v,val,tmpArr,newStyle,tmp,isLegal,j,jlen,pxV,attr,i,len;
        for(i = 0, len = attrs.length ; i < len ; ++i){
            attr = attrs[i];
            if (attr && attr.nodeType === 2) {
                val = attr.value.replace(/pt/g,"px");
                //保留pre里面的data属性,适配适配播放
                if (nodeName === "PRE" && (attr.nodeName === "data" || attr.nodeName === "class")) {
                    val = _this._unhtmlForUrl(val);
                    ele.setAttribute(attr.nodeName, val);
                    return true;
                }
                if (legalAttr.indexOf(attr.nodeName) < 0) {
                    ele.removeAttribute(attr.nodeName);
                } else if (attr.nodeName === "class" && (val.indexOf('_section_div_') < 0) && nodeName !== "PRE") {
                    ele.removeAttribute(attr.nodeName);
                } else {//处理属性值，防止xss
                    if (attr.nodeName !== "style") {
                        val = _this._unhtmlForUrl(val);
                        ele.setAttribute(attr.nodeName, val);
                    }else{//处理style里面不合法的样式
                        tmpArr = val.split(";");
                        newStyle = [];
                        for(j = 0 , jlen = tmpArr.length ; j < jlen ;++j){
                            tmp = tmpArr[j];
                            if(tmp !== ""){
                                tmp = tmp.split(":");
                                if(tmp.length > 1){
                                    k = tmp[0].leftTrim().rightTrim();
                                    v = tmp[1].leftTrim().rightTrim();
                                    isLegal = legalCssStyleNames.indexOf(k) >= 0 || ( isP && pLegalCssStyleNames.indexOf(k) >= 0 );
                                    if (isLegal) {
                                        if (k === "font-family") {
                                            if (v === 'Microsoft Yahei') {
                                                v = '微软雅黑';
                                            }
                                            if (legalFontFamilys.indexOf(v) < 0) {//非法
                                                v = undefined;
                                            }
                                        } else if (v.indexOf("pt") > 0) { //pt转像数
                                            if (v.indexOf("pt") > 0) {
                                                v = v.replace(/\.[0]+pt/, "");
                                                pxV = fontSizePt2Px[v];
                                                if(pxV ){
                                                    v = pxV;
                                                }else{
                                                    v = v + "px";
                                                }
                                            } 
                                        } else if (k === "font-weight") {
                                            if (legalFontWeights.indexOf(v) < 0) {
                                                v = undefined;
                                            }
                                        } else if (k === "font-style") {
                                            if (legalFontStyles.indexOf(v) < 0) {
                                                v = undefined;
                                            }
                                        } else if (k === "text-decoration") {
                                            if (legalTextDecorations.indexOf(v) < 0) {
                                                v = undefined;
                                            }
                                        } else if (k === "text-align") {
                                            if (legalTextAligns.indexOf(v) < 0) {
                                                v = undefined;
                                            }
                                        } 
                                        if(v){
                                            newStyle.push( k + ":" + v);
                                        }                                        
                                    }
                                }                               
                            }
                        }
                        ele.setAttribute(attr.nodeName, newStyle.join(";"));
                    }
                }
            }
        }
        if(recursion){
          for(i =0 ,len = ele.children.length ; i < len ; ++i){
              this._removeUnlegalAttr(ele.children[i] ,recursion );
          }
        }
    },
    /**获取鼠标光标所在的jq对象容器
     * 内部走getDomRange().commonAncestorContainer
     * ***/
    getAnchorJqNode: function () {
        var range = this.getDomRange();
        var anchorNode = range.commonAncestorContainer;
        var node;
        if (anchorNode.nodeType === 3) {
            node = $(anchorNode.parentNode);
        } else {
            node = $(anchorNode);
        }
        return node;
    },
    /***删除键放开后，检查被删除的table对象，处理顺序列表问题
     * ***/
    onDeleteKeyup: function (key) {
        //console.log("key up >>>>>>>>>>>>>>>>>>>>");
        var _this = this;
        _this.removeUselessComponent();
        clearTimeout(this["onDeleteKeyupEvent"]);
        //清理选区，压入undo
        _this.clearUserRange();
        var anchor = _this.getAnchorJqNode();
        //修正空br段落情况
        if (anchor.hasClass("_section_div_")) {
            var childs = anchor.children();
            if (childs.length === 1 && childs.first()[0].tagName === "BR") {
                var id = getUUID();
                anchor.html('<span style="' + eConfig.defaultStyle + '" id="' + id + '">\u200B</span>');
                var node = anchor.children().first();
                _this.moveToEnd(node);
                anchor = _this.getAnchorJqNode();
            }
        }
        if (anchor[0].tagName === "SPAN") {
            var $p = anchor.parent();
            var txt = $p.text();
            if ($p[0].tagName === "LI" && (txt === "\u200B" || txt === "")) {
                var preLi = $p.prev();
                if (preLi.length === 0) {
                    var liParent = preLi.parent();
                    var newSpan = _this._getSpan().insert(liParent);
                    _this.moveToEnd(newSpan);
                    anchor = _this.getAnchorJqNode();
                } else {
                    $p.remove();
                    _this.moveToEnd(preLi);
                    anchor = _this.getAnchorJqNode();
                }
                $p = anchor.parent();
                txt = $p.text();
            }
            var prevEle = $p.prev();
            var nextEle = $p.next();
            if(prevEle.length > 0 && nextEle.length > 0){
                var isEQ1 = _this._getSectionSeqDatas(prevEle).isSeq;
                var isEQ2 = _this._getSectionSeqDatas(nextEle).isSeq;
                if(isEQ1 && isEQ2){
                    _this._fixSeqNum(prevEle, $p, nextEle);
                }   
            }                  
            if (_this.isEmptySection) {
                if (key === 8 && txt === "") {
                    console.log("删除空段落》》》");
                    var prev = $p.prev("._section_div_");
                    if (prev.length > 0) {
                        _this.moveToEnd(prev);
                        $p.remove();
                    }
                } else {
                }
            } else {//如果是图片
                var img = anchor.children("img");
                if (img.length > 0) {
                    img.remove();
                } else {
                    //批量删除空span
                    var delSpan = anchor;
                    var move2end = false;
                    while (delSpan.children().length === 0 && delSpan.prev().length !== 0 && delSpan.text() === "\u200B") {
                        var tmp = delSpan.prev();
                        delSpan.remove();
                        delSpan = tmp;
                        move2end = true;
                    }
                    if (move2end) {
                        _this.moveToEnd(delSpan);
                    }
                    //避免删除后焦点在td中，table下发没有段落内容
                    var nodeAnchor = _this.getAnchorJqNode();
                    var isInTd = false;
                    while (nodeAnchor.length > 0) {
                        var name = nodeAnchor[0].tagName;
                        if (name === "TD") {
                            isInTd = true;
                        }
                        if (name === "LI" || name === "DIV") {
                            break;
                        }
                        nodeAnchor = nodeAnchor.parent();
                    }
                    if (isInTd) {
                        if (nodeAnchor.next().length === 0) {
                            var nextp = _this.createPElement().insertAfter(nodeAnchor);
                            _this.moveToEnd(nextp);
                        }
                    }
                }
            }
        }
        _this.saveUserRange();
        /** 
         * 处理backspace连续按键删除，当前段落被删除场景下的撤销重做问题，在这里修正等待入栈的记录
         * 提取待入栈的undo数据，对比当前鼠标所在段落，检测鼠标所在的段落是否发生变化
         * 如果发生了变化， 则将需要替换的段落改为当前段落，替换内容也要将当前段落加入
         * ***/
        var rec = this["undoRedoRec"];
        if (rec && rec.replaceSectionId.length === 1) {
            anchor = _this.getAnchorJqNode();
            var pele = anchor;
            while (pele.length > 0) {
                if (pele.hasClass("_section_div_")) {
                    break;
                }
                pele = pele.parent();
            }
            var pid = pele.attr("id");
            if (pid !== rec.replaceSectionId[0]) {//段落发生了变化
                rec.replaceSectionId[0] = pid;
                var newHtml = [];
                var cHtml = pele[0].outerHTML;
                var replaceHtml = [];
                var nextSapn = anchor.next();
                while (nextSapn.length > 0) {
                    replaceHtml.push(nextSapn[0].outerHTML);
                    nextSapn = nextSapn.next();
                }
                cHtml = cHtml.replace(replaceHtml.join(""), "");
                newHtml.push(cHtml);
                for (var i = 0, len = rec.html.length; i < len; ++i) {
                    newHtml.push(rec.html[i]);
                }
                rec.html = newHtml;
            }
        }
    },
    /***
     * 如果是序列，则需要修正序列
     * 通过当前行，上一行、下一行对比三行进行顺序列表调整
     * ***/
    _fixSeqNum: function (prevEl, curEl, nextEl) {
        //console.log("修正序列》》》》》》》》》》》");
        var prevSeq = this._getSectionSeqDatas(prevEl);
        var curSeq = this._getSectionSeqDatas(curEl);
        var nextSeq = this._getSectionSeqDatas(nextEl);
        var c1, c2, c3, nextSeqNum, chSeqData;
        var indx1, indx2, indx3;
        if (prevSeq.isSeq && curSeq.isSeq && nextSeq.isSeq) {//三个都是序列
            c1 = this._isSameSeq(prevSeq.seqNumTxt, curSeq.seqNumTxt, prevSeq.seqEl, curSeq.seqEl);
            c2 = this._isSameSeq(curSeq.seqNumTxt, curSeq.seqNumTxt, nextSeq.seqEl, nextSeq.seqEl);
            if (c1 && c2) {
                if (prevSeq.isChSeq) {//中文序列
                    indx1 = getChSeqIndex(prevSeq.seqNum);
                    indx2 = getChSeqIndex(curSeq.seqNum);
                    indx3 = getChSeqIndex(nextSeq.seqNum);
                    c3 = indx1 === (indx2 - 1) && indx2 === (indx3 - 1);
                    if (!c3) {
                        chSeqData = getChNextSeq(prevSeq.seqNum);
                        this._updateSeq(chSeqData, curSeq);
                    }
                } else {
                    c3 = prevSeq.seqNum === (curSeq.seqNum - 1) && curSeq.seqNum === (nextSeq.seqNum - 1);
                    if (!c3) {//需要更新序列                        
                        nextSeqNum = prevSeq.seqNum + 1;
                        this._updateSeq(nextSeqNum, curSeq);
                    }
                }
            }
        } else if (prevSeq.isSeq && nextSeq.isSeq && !curSeq.isSeq) {//当前段落不是序列，但上下段落是序列
            c1 = this._isSameSeq(prevSeq.seqNumTxt, nextSeq.seqNumTxt, prevSeq.seqEl, nextSeq.seqEl);
            if (c1) {
                if (prevSeq.isChSeq) {
                    chSeqData = getChNextSeq(prevSeq.seqNum);
                    this._updateSeq(chSeqData, nextSeq);
                } else {
                    nextSeqNum = prevSeq.seqNum + 1;
                    this._updateSeq(nextSeqNum, nextSeq);
                }
            }
        } else if (!prevSeq.isSeq && !curSeq.isSeq && nextSeq.isSeq) {
            if (nextSeq.isChSeq) {
                this._updateSeq({ index: 0, seq: "一" }, nextSeq);
            } else {
                this._updateSeq(1, nextSeq);
            }
        } else if (!prevSeq.isSeq && curSeq.isSeq && nextSeq.isSeq) {
            c1 = this._isSameSeq(curSeq.seqNumTxt, nextSeq.seqNumTxt, curSeq.seqEl, nextSeq.seqEl);
            if (c1) {
                if (curSeq.isChSeq) {
                    indx2 = getChSeqIndex(curSeq.seqNum);
                    indx3 = getChSeqIndex(nextSeq.seqNum);
                    c3 = indx2 !== indx3 - 1;
                    if (c3) {//需要更新序列
                        chSeqData = getChNextSeq(curSeq.seqNum);
                        this._updateSeq(chSeqData, nextSeq);
                    }
                } else {
                    nextSeqNum = curSeq.seqNum + 1;
                    this._updateSeq(nextSeqNum, nextSeq);
                }
            }
        }
    },
    /***更新序列
     * 中文序列时候 nextSeqNum = {index: seq:}
     * 非中文序列 nextSeqNum = 阿拉伯数字 
     * ***/
    _updateSeq: function (nextSeqNum, nextSeq) {
        var el = nextSeq.seqEl;
        var chSeqIndex;
        if (nextSeq.isChSeq) {//中文序列
            chSeqIndex = nextSeqNum.index;
            el.html(nextSeq.seqNumTxt.replace(nextSeq.seqNum, nextSeqNum.seq));
        } else {
            el.html(nextSeq.seqNumTxt.replace(/\d+/g, nextSeqNum));
        }
        var sesionEl = el.parent().next();
        var sesionElSeq, c, chSeq;
        var count = 0;
        while (sesionEl.length > 0 && (sesionEl[0].tagName === "DIV" || sesionEl[0].tagName === "P")) {
            sesionElSeq = this._getSectionSeqDatas(sesionEl);
            if (sesionElSeq.isSeq) {
                c = this._isSameSeq(nextSeq.seqNumTxt, sesionElSeq.seqNumTxt, nextSeq.seqEl, sesionElSeq.seqEl);
                if (c) {
                    if (sesionElSeq.isChSeq) {
                        chSeqIndex++;
                        chSeq = chSeqArray[chSeqIndex];
                        sesionElSeq.seqEl.html(sesionElSeq.seqNumTxt.replace(sesionElSeq.seqNum, chSeq));
                    } else {
                        nextSeqNum++;
                        sesionElSeq.seqEl.html(sesionElSeq.seqNumTxt.replace(/\d+/g, nextSeqNum));
                    }
                    if (sesionElSeq.nodeText !== sesionElSeq.seqNumTxt) {//需要补充一个span内容
                        sesionElSeq.nodeText = sesionElSeq.nodeText.replace(sesionElSeq.seqNumTxt, "");
                        this._getSpan().html(sesionElSeq.nodeText).insertAfter(sesionElSeq);
                    }
                } else {
                    break;
                }
            } else {
                count++;
                if (count > 5) {
                    break;
                }
            }
            sesionEl = sesionElSeq.seqEl.parent().next();
        }
    },
    /**是否是相同类型的序列**/
    _isSameSeq: function (seq1, seq2, seqEl1, seqEl2) {
        var isTrue;
        seq1 = seq1.replace("\u200B", "");
        seq2 = seq2.replace("\u200B", "");
        if (/\d+/.test(seq1) && /\d+/.test(seq2)) {
            seq1 = seq1.replace(/\d+/g, "");
            seq2 = seq2.replace(/\d+/g, "");
            isTrue = seq1 === seq2;
        } else {//中文序列 [一二三四五六七八九十]+
            seq1 = seq1.replace(/[一二三四五六七八九十]+/, "");
            seq2 = seq2.replace(/[一二三四五六七八九十]+/, "");
            isTrue = seq1 === seq2;
        }
        if (isTrue) { //进一步比较padding-left
            var pading1 = seqEl1.parent().css("padding-left");
            var pading2 = seqEl2.parent().css("padding-left");
            isTrue = pading1 === pading2;
        }
        return isTrue;
    },
    /***
     * 替换完所有不可见字符及空格符
     * srcText :原文本
     * replaceBlank  是否替换空字符
     * ****/
    _replaceAllEmptyChar: function (srcText, replaceBlank) {
        var res = [], tmp;
        if (replaceBlank) {
            srcText = srcText.replace(/\s+/g, "");
        }
        srcText = srcText.replace(/\u200b/g, "");
        return srcText;
    },
    /***
     * 用于自动序列 section = div / p
     * 获取段落的序列信息
     * return {
            isChSeq :是否是中文序列
            isSeq: 是否是序列,
            seqEl: 序列元素,
            emptyEl: 序列元素前方空元素,
            seqNum: 序列数字,
            seqNumTxt: 序列号文本包括空格,
            nodeText: seqEl节点的内容文本
        }
     * ***/
    _getSectionSeqDatas: function (section) {
        var firstTxtEl = section.children().first();
        var txt = firstTxtEl.text();
        var emptyEl = [],
            plainTxt,
            seqNum,
            seqNumTxt,
            isSeq = false,
            isChSeq = false,
            exeRes;
        plainTxt = this._replaceAllEmptyChar(txt, true);
        while (plainTxt === "") {
            emptyEl.push(firstTxtEl);
            firstTxtEl = firstTxtEl.next();
            if (firstTxtEl.length === 0) {
                break;
            }
            txt = firstTxtEl.text();
            plainTxt = this._replaceAllEmptyChar(txt, true);
        }
        //如果plainTxt只是 1,2,3..... 一，二，三需要进一步检查下一个相邻元素是否是【. 、】
        var reg = new RegExp(testSeq);
        if (reg.test(plainTxt)) {
            //console.log("修正序列span 》》》》》》》");
            var nextSpan = firstTxtEl.next();
            var nextTxt = nextSpan.text();
            exeRes = /^[\s\\u200b]*([\.、\)）])[\s\\u200b]*/.exec(nextTxt);
            if (exeRes) {
                var dot = exeRes[0];
                nextSpan.text(nextTxt.replace(dot, ""));
                txt = txt + dot;
                firstTxtEl.text(txt);
            }
        }
        reg = new RegExp(seqexp);
        exeRes = reg.exec(this._replaceAllEmptyChar(txt));
        if (exeRes && exeRes.length > 2) {
            seqNumTxt = exeRes[0];
            if (/^\d+$/.test(exeRes[2])) {
                seqNum = parseInt(exeRes[2]);
            } else {
                seqNum = exeRes[2];
                isChSeq = true;
            }
            isSeq = true;
        }
        return {
            isChSeq: isChSeq,
            isSeq: isSeq,
            seqEl: firstTxtEl,
            emptyEl: emptyEl,
            seqNum: seqNum,
            seqNumTxt: seqNumTxt,
            nodeText: txt
        };
    },        /**
    *通知工具栏 
    **/
    _notifyTools: function (operator, params) {
        if (this.tools && this.tools.notifyTools) {
            this.tools.notifyTools({
                "operator": operator,
                "params": params
            });
        }
    },
    /**
     *重做、撤销通知 
     **/
    _undoRedoNotify: function (name) {
        var prs = {
            undoStackSize: this.undoStack.getLength(),
            redoStackSize: this.redoStack.getLength()
        };
        this._notifyTools(name, prs);
    },
    /**
     * 根据this.range 获取选区涵盖的所有段落
     * forFn：循环回调
     * return :段落数组
     * ***/
    _getRangeSections: function (forFn) {
        var res = [];
        if (!this.range && this.clickActivedObject) {
            var jqObj = this.clickActivedObject.jqObj;
            while (jqObj.length > 0) {
                if (jqObj.hasClass("_section_div_")) {
                    res.push(jqObj);
                    break;
                }
                jqObj = jqObj.parent();
            }
            return res;
        }
        if (!this.range) {
            return res;
        }
        var startContainer = this.range.startContainer; //开始节点
        if (startContainer.nodeType === 1) {
            var tmp = $(startContainer);
            while (tmp.length > 0) {
                if (tmp.hasClass("_section_div_")) {
                    res.push(tmp);
                    if (forFn) {
                        forFn(tmp);
                    }
                    break;
                }
                tmp = tmp.parent();
            }
            return res;
        }
        var endContainer = this.range.endContainer; //结束节点
        var startNode = $(startContainer.parentNode);
        var endNode = $(endContainer.parentNode);
        var startSection = startNode;
        while (startSection.length > 0) {
            if (startSection[0].tagName === "DIV") {
                break;
            }
            startSection = startSection.parent();
        }
        var endSection = endNode;
        while (endSection.length > 0) {
            if (endSection[0].tagName === "DIV") {
                break;
            }
            endSection = endSection.parent();
        }
        if (forFn) {
            forFn(startSection);
        }
        res.push(startSection);
        var nextSection = startSection.next();
        if (endSection[0] !== startSection[0]) {
            while (nextSection.length > 0 && nextSection[0] !== endSection[0]) {
                if (forFn) {
                    forFn(nextSection);
                }
                res.push(nextSection);
                nextSection = nextSection.next();
            }
        }
        if (endSection[0] !== startSection[0]) {
            if (forFn) {
                forFn(endSection);
            }
            res.push(endSection);
        }
        return res;
    },
    /**关闭右键菜单**/
    _closeCxtMenu: function () {
        clearTimeout(this["_closeCxtMenuTimer"]);
        var _this = this;
        this["_closeCxtMenuTimer"] = setTimeout(function () {
            _this._closeCxtMenuImd();
        }, 500);
    },
    _closeCxtMenuImd:function(){
        var m = getSingleton("TableProps",this);
        if (m) {
            m.hide();
        }
        if (this["mousemenu"]) {
            this["mousemenu"].hide();
        }
        this.closeAllWindow();
    },
    /***
     *执行前 ，判断是否需要选区，是否需要undo记录
     ***/
    beforeExecute: function (method, params, button) {
        this._closeCxtMenuImd();
        //源码状态不能执行的操作过滤
        if (method !== "save" && method !== "source" && this["sourceView"]) {
            var display = this["sourceView"].css("display");
            if (display !== "none") {
                return false;
            }
        }
        var go = true;
        if (this.opts.beforeExecute) {
            var res = this.opts.beforeExecute(method, params, button);
            if (typeof res !== 'undefined') {
                go = res;
            }
        }
        /***
         * 该命令是否需要range选区
         * ***/
        if (params.needRange || typeof params.needRange === "undefined") {
            go = typeof this.range !== "undefined";
        }
        /**
         * 没有选区，但是可能clickActivedObject需要执行自定义的处理
         * **/
        if (this.clickActivedObject) {
            go = true;
        }
        if (go) {           
            /***创建一个undo记录***/
            if (params.undo || params.delayUndo) {
                this._onChange();//变化监听
                var isClear = method === "clear";
                if (method === "eraser") { //清除格式支持值清除选择区域
                    var range = this.getDomRange();
                    if (range.collapsed) {
                        isClear = true;
                    } else {
                        isClear = false;
                    }
                }
                this._makeUndoDataByFocus(isClear);
                if (params.undo) {
                    this._putUndo();
                } else {
                    var delay = 500;
                    if (typeof params.delay !== "undefined") {
                        delay = params.delay;
                    }
                    this._putUndoDelayed(delay);
                }
            }
        }
        return go;
    },
    /***
     *执行后 
     ***/
    afterExecute: function (method, params, button) {
        this.cssing = undefined;
        if (this.opts.afterExecute) {
            this.opts.afterExecute(method, params, button);
        }
    },
    /**
     * method:工具栏按钮事件名称
     * params:参数，如果该操作需要撤销，需要传递undo=true参数
     **/
    execute: function (method, params, button) {
        console.log("execute >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" + method);
        if (this.beforeExecute(method, params, button)) {
            if (typeof this[method] === "function") {
                //需要选区,选执行一次选取设置
                var needRange = typeof params.needRange === "undefined" || params.needRange;
                if (needRange) {
                    this.setPaintTarget();
                } else if (params.createTargetsByRange) {
                    this.createTargetsByRange();
                }
                var go = true;
                if (this.clickActivedObject) { //如果存在点击对象，进走对象的css修饰
                    var methodName = this.clickActivedObject.className + "Css";
                    if (typeof this[methodName] === "function") {
                        go = this[methodName](method, params, button); //执行特有的修饰
                    }
                }
                if (needRange && this.painTargets.length === 0) {
                    return;
                }
                var ret;
                if (go) {
                    ret = this[method](params, button);
                }                
                this.afterExecute(method, params, button);
                return ret;
            } else {
                alert("找不到handler[" + method + "]");
            }
        }
    },
    /** 恢复段落auto宽度**/
    resetSectionWidth: function () {
        this._onChange();
        var pEl = this.startPElement;
        var pArray = [];
        while (pEl.length > 0) {
            pArray.push(pEl);
            pEl.addClass("k_editor_closed_section");
            pEl.css({ "width": "auto", "margin-left": 0 });
            if (pEl[0] === this.endPElement[0]) {
                break;
            }
            pEl = pEl.next();
        }
        var _this = this;
        setTimeout(function () {
            for (var i = 0, len = pArray.length; i < len; ++i) {
                pArray[i].removeClass("k_editor_closed_section");
            }
        }, 1000);
        if (this.sectionResizeBar) {
            this.sectionResizeBar.remove();
            this.sectionResizeBar = undefined;
        }
        if (this.sectionResizeBar2) {
            this.sectionResizeBar2.remove();
            this.sectionResizeBar2 = undefined;
        }
    },   
    /**设置段落宽度，高亮对应的段落，并显示拖动线
     * onlyHighlight 不需要拖动线出现,只需要高亮当前光标所在的段落
     * **/
    setSectionWidth: function (onlyHighlight) {
        //console.log("setSectionWidth>>>>>>>>> ");
        var _this = this;
        var startPElement = this.startPElement;
        var endPElement = this.endPElement;
        if(!startPElement || startPElement.length === 0){
            $B.alert(eConfig.label.lostfocus,2);
            return;
        }
        var el = startPElement;
        var width = el.outerWidth();
        if (this.resizePelement && this.resizePelement.length > 0) {
            for (var i = 0, len = this.resizePelement.length; i < len; ++i) {
                this.resizePelement[i].removeClass("k_editor_closed_section");
            }
        }
        this.resizePelement = [];
        var fixCount = 0;//预防未知的死循环
        var tmpEl = startPElement;
        while (true) {
            if (parseFloat(el.css("padding-left").replace("px", "")) > parseFloat(tmpEl.css("padding-left").replace("px", ""))) {
                el = tmpEl;
            }
            if (width < tmpEl.outerWidth()) {
                width = tmpEl.outerWidth();
            }
            this.resizePelement.push(tmpEl);
            tmpEl.addClass("k_editor_closed_section");
            if (tmpEl[0] === endPElement[0]) {
                break;
            }
            if (fixCount > 2000) {
                break;
            }
            fixCount++;
            tmpEl = tmpEl.next();
        }
        if (this.sectionResizeBar) {
            this.sectionResizeBar.remove();
        }
        if (this.sectionResizeBar2) {
            this.sectionResizeBar2.remove();
        }
        if(typeof onlyHighlight !== "undefined" && !$.isPlainObject(onlyHighlight)){//只需要高亮 当前激活的段落
            return;
        }
        var fixLeftVal = 0;
        //处理浮动文本场景
        if (this.$input.hasClass("k_editor_float_input")) {
            fixLeftVal = this.$input.parent().position().left;
        }
        var tmpLeft = parseFloat(el.css("margin-left").replace("px", ""));
        var h = this.$inputWrap[0].scrollHeight;//+ this.tools.$wrap.height();
        var sectionResizeBar = $("<div class='k_edit_section_resiez_bar' style='cursor : w-resize;left:" + (width + fixLeftVal + tmpLeft) + "px;height:" + h + "px;position:absolute;top:0;width:5px;z-index:9999999999;border-right:2px solid #FA001D; background:none;opacity:0.65;'></div>");
        this.sectionResizeBar = sectionResizeBar;
        sectionResizeBar.attr("title", eConfig.label.sectionWidth.replace("[x]", width + "像数"));
        var startWidthArray = [];
        var maxLeft = this.$input.width() + fixLeftVal;
        sectionResizeBar.appendTo(this.$inputWrap).draggable({
            axis: 'h',
            cursor: "w-resize",
            onStartDrag: function (args) { //开始拖动
                if (_this.resizeBox) {
                    _this.resizeBox.hide();
                }
                _this._onChange();
                for (var i = 0, len = _this.resizePelement.length; i < len; ++i) {
                    startWidthArray.push(_this.resizePelement[i].outerWidth());
                }
                console.log("onStartDrag >>>>>>");
            },
            onDrag: function (args) { //拖动中               
                var state = args.state;
                var data = state._data;
                var left = data.left;
                var update = true;
                if (left < 12) {
                    left = 12;
                    update = false;
                }
                if (left > maxLeft) {
                    left = maxLeft;
                    update = false;
                }
                if (update) {
                    var firstW;
                    for (var i = 0, len = _this.resizePelement.length; i < len; ++i) {
                        var w = startWidthArray[i] + data.leftOffset;
                        if (!firstW) {
                            firstW = w;
                        }
                        _this.resizePelement[i].outerWidth(w);
                    }
                    _this.sectionResizeBar.attr("title", eConfig.label.sectionWidth.replace("[x]", firstW + "像数"));
                }
            },
            onStopDrag: function () {
                startWidthArray = [];
            }
        });
        var inputPaddingLeft = parseFloat(this.$input.css("padding-left").replace("px", ""));       
        var paddleft = tmpLeft + inputPaddingLeft + fixLeftVal;
        var startPaddingArray = [];
        var maxPadding;
        var startElWidthArray = [];
        this.sectionResizeBar2 = $("<div class='k_edit_section_resiez_bar' style='cursor : w-resize;left:" + paddleft + "px;height:" + h + "px;position:absolute;top:0;width:5px;z-index:9999999999;border-left:2px solid #FA001D;background:none;opacity:0.65;'></div>");
        this.sectionResizeBar2.attr("title", eConfig.label.sectionPadding.replace("[x]", tmpLeft + "像数"));
        this.sectionResizeBar2.appendTo(this.$inputWrap).draggable({
            axis: 'h',
            cursor: "w-resize",
            onStartDrag: function (args) { //开始拖动 
                if (_this.resizeBox) {
                    _this.resizeBox.hide();
                }
                _this._onChange();
                var pEl, startPadding, tmpWidth, tmpPadding;
                for (var i = 0, len = _this.resizePelement.length; i < len; ++i) {
                    pEl = _this.resizePelement[i];
                    tmpWidth = pEl.width();
                    startElWidthArray.push(tmpWidth);
                    startPadding = parseFloat(pEl.css("margin-left").replace("px", ""));
                    startPaddingArray.push(startPadding);
                    tmpPadding = startPadding + tmpWidth - 50 + paddleft;
                    if (!maxPadding) {
                        maxPadding = tmpPadding;
                    } else if (maxPadding > tmpPadding) {
                        maxPadding = tmpPadding;
                    }
                }
            },
            onDrag: function (args) { //拖动中
                var state = args.state;
                var data = state._data;
                var left = data.left;
                var update = true;
                if (left < inputPaddingLeft) {
                    left = inputPaddingLeft;
                    update = false;
                }
                if (left > maxPadding) {
                    left = maxPadding;
                    update = false;
                }
                if (update) {
                    var pEl, startPadding, newPadding, startElWidth, fisrtPadding;
                    for (var i = 0, len = _this.resizePelement.length; i < len; ++i) {
                        pEl = _this.resizePelement[i];
                        startPadding = startPaddingArray[i];
                        startElWidth = startElWidthArray[i];
                        newPadding = startPadding + data.leftOffset;
                        pEl.css({
                            "margin-left": newPadding
                        });
                        if (!fisrtPadding) {
                            fisrtPadding = newPadding;
                        }
                    }
                    _this.sectionResizeBar2.attr("title", eConfig.label.sectionPadding.replace("[x]", fisrtPadding + "像数"));
                }
            },
            onStopDrag: function () {
                maxPadding = undefined;
                startPaddingArray = [];
                startElWidthArray = [];
            }
        });
    },
    /**循环所有选择的元素，fn循环回调**/
    foreachTargets: function (fn) {
        for (var i = 0, len = this.painTargets.length; i < len; ++i) {
            var t = this.painTargets[i];
            if (!t.hasClass("_exclude_")) {
                var isBreak = fn(t, i);
                if (typeof isBreak !== 'undefined' && !isBreak) {
                    break;
                }
            }
        }
    },
    /**是否是跨段落的选区**/
    isCrossPElement: function () {
        this.setStartAndEndPElementByRange();
        return this.startPElement[0] !== this.endPElement[0];
    },
    /**
     * 根据range找到开始、结束段落
     * this.startPElement 
     * this.endPElement
     * **/
    setStartAndEndPElementByRange: function () {       
        if (this.range) {
            var start = this.range.startContainer;
            if (start.nodeType === 3) {
                start = $(start).parent();
            } else {
                start = $(start);
            }
            while (start.length > 0) {
                if (start.hasClass("_section_div_")) {
                    break;
                }
                start = start.parent();
            }
            var end = this.range.endContainer;
            if (end === this.range.startContainer) {
                end = start;
            } else {
                if (start.nodeType === 3) {
                    end = $(end).parent();
                } else {
                    end = $(end);
                }
                while (end.length > 0) {
                    if (end.hasClass("_section_div_")) {
                        break;
                    }
                    end = end.parent();
                }
            }
            this.startPElement = start;
            this.endPElement = end;
        }
    },
    /**循环选区里的p段落，fn回调**/
    foreachPTargets: function (fn) {
        var i = 0;
        var start = this.startPElement;
        if (!start || start.length === 0) {
            return;
        }
        var go = true;
        if (!start.hasClass("_exclude_")) {
            go = fn(start, i);
        }
        if (typeof go === "undefined") {
            go = true;
        }
        if (go && this.startPElement[0] !== this.endPElement[0]) {
            i = ++i;
            var next = this.startPElement.next();
            while (go && next.length > 0) {
                if (!next.hasClass("_exclude_")) {
                    go = fn(next, i);
                }
                if (typeof go === "undefined") {
                    go = true;
                }
                if (this.endPElement[0] === next[0]) {
                    break;
                }
                next = next.next();
                i = ++i;
            }
        }
    },/**
   * 获取选区里所有颜色的css样式
   * onlyForBrush 是否只用于格式刷的
   * need2p:应用于格式刷时候，是否需要刷段落样式
   * forFontTitle:应用于关联工具栏上的标题/正文
   * **/
    _getRangeCss: function (forBrush,need2p,forFontTitle) {
        var eles, i, len, node, fontSize, fontWeight, fontColor, backgroundColor,
            fontStyle, textDesc, textAlign, verticalAlign, fontFamily;
        var _this = this;
        var css = {
            "font-size": undefined,
            "font-weight": undefined,
            "color": undefined,
            "background-color": undefined,
            "font-style": undefined,
            "text-align": undefined,
            "text-decoration": undefined
        };
        var isEmpty = {};
        var setPeleCssFn = function (node) {
            textAlign = node.css("text-align");
            if (!css["text-align"] && !isEmpty["text-align"]) {
                css["text-align"] = textAlign;
            } else if (css["text-align"] !== textAlign) {
                css["text-align"] = undefined;
                isEmpty["text-align"] = true;
            }
        };
        var setcssFn = function (node) {
            fontSize = node.css("font-size");
            fontWeight = node.css("font-weight");
            fontColor = node.css("color");
            backgroundColor = node.css("background-color");
            fontStyle = node.css("font-style");
            textDesc = node.css("text-decoration");
            verticalAlign = node.css("vertical-align");
            fontFamily = node.css("font-family");

            if (!css["font-family"] && !isEmpty["font-family"]) {
                css["font-family"] = fontFamily;
            } else if (css["font-family"] !== fontFamily) {
                css["font-family"] = undefined;
                isEmpty["font-family"] = true;
            }
            if (!css["vertical-align"] && !isEmpty["vertical-align"]) {
                css["vertical-align"] = verticalAlign;
            } else if (css["vertical-align"] !== verticalAlign) {
                css["vertical-align"] = undefined;
                isEmpty["vertical-align"] = true;
            }
            if (!css["text-decoration"] && !isEmpty["text-decoration"]) {
                css["text-decoration"] = textDesc;
            } else if (css["text-decoration"] !== textDesc) {
                css["text-decoration"] = undefined;
                isEmpty["text-decoration"] = true;
            }
            if (!css["font-style"] && !isEmpty["font-style"]) {
                css["font-style"] = fontStyle;
            } else if (css["font-style"] !== fontStyle) {
                css["font-style"] = undefined;
                isEmpty["font-style"] = true;
            }
            if (!css["background-color"] && !isEmpty["background-color"]) {
                css["background-color"] = backgroundColor;
            } else if (css["background-color"] !== backgroundColor) {
                css["background-color"] = undefined;
                isEmpty["background-color"] = true;
            }
            if (!css["color"] && !isEmpty["color"]) {
                css["color"] = fontColor;
            } else if (css["color"] !== fontColor) {
                css["color"] = undefined;
                isEmpty["color"] = true;
            }
            if (!css["font-weight"] && !isEmpty["font-weight"]) {
                css["font-weight"] = fontWeight;
            } else if (css["font-weight"] !== fontWeight) {
                css["font-weight"] = undefined;
                isEmpty["font-weight"] = true;
            }
            if (!css["font-size"] && !isEmpty["font-size"]) {
                css["font-size"] = fontSize;
            } else if (css["font-size"] !== fontSize) {
                css["font-size"] = undefined;
                isEmpty["font-size"] = true;
            }
        };
        if (this.painTargets.length === 0) {
            this.setPaintTarget();
        }
        eles = this.painTargets;
        if (forBrush) {
            for (i = 0, len = eles.length; i < len; ++i) {
                node = eles[i];
                setcssFn(node);
            }
            var pCss = {};//刷上段落的 margin-left，background-color
            if(need2p){
                this.foreachPTargets(function (p, i) {
                    if (!p.hasClass("_exclude_")) {
                        var cssObj = _this._style2CssObject(p);
                        cssObj["margin-top"] = p.css("margin-top");
                        cssObj["margin-bottom"] = p.css("margin-bottom");
                        cssObj["text-indent"] = p.css("text-indent");
                        cssObj["line-height"] = p.css("line-height");
                        $.extend(pCss,cssObj);
                    }
                });
                css.pCss = pCss;
            }
        } else {
            var child, container, pEl;
            if (this.painTargets.length > 0) {
                for (i = 0, len = this.painTargets.length; i < len; ++i) {
                    child = this.painTargets[i];
                    setcssFn(child);
                }
                pEl = this.startPElement;
                while (pEl.length > 0) {
                    setPeleCssFn(pEl);
                    if (pEl[0] === this.endPElement[0]) {
                        break;
                    }
                    pEl = pEl.next();
                }
            } else {
                var range = this.range;
                if (range) {
                    var ancContainer = range.commonAncestorContainer;
                    if (ancContainer.nodeType === 3) {
                        container = $(ancContainer.parentNode);
                        setcssFn(container);
                    }else{
                        container = $(ancContainer);
                    }
                    pEl = container;
                    while (pEl.length > 0) {
                        if (pEl[0].tagName === "P") {
                            break;
                        }
                        pEl = pEl.parent();
                    }
                    setPeleCssFn(pEl);
                }
            }
        }
        if(forFontTitle && this.startPElement && this.endPElement){
            if(this.startPElement[0] === this.endPElement[0]){
                var h = this.startPElement.height() ;
                var lineH = this.startPElement.css("line-height");
                if(lineH){                   
                    var lh  = parseInt(lineH.replace("px","")) * 1.3;
                    if(h < lh){
                        var fSize,fWeight;
                        this.startPElement.children("span").each(function(){
                            var  $s = $(this);
                            if($s.children("image").length > 0){
                                return true;
                            }
                            var  size = $s.css("font-size");
                            var  weight = $s.css("font-weight");
                            if(!fSize){
                                fSize = size;
                            }else if(fSize !== size){
                                fSize = "14px";
                            }
                            if(!fWeight){
                                fWeight = weight;
                            }else if(fWeight !== weight){
                                fWeight = "400";
                            }
                        });
                        if(fSize && fWeight){
                            css["fontTitle"] = {
                                "line-height": this.startPElement.css("line-height"),
                                "font-size": fSize,
                                "font-weight": fWeight
                            };
                        }
                    }
                }else{
                    console.log("line height >> is undefined >>>");
                }
            }
        }
        return css;
    },
    _hideOthersIconOnTimer:function(){
        var _this = this;
        clearTimeout(this.hideOthersIconTimer);
        this.hideOthersIconTimer = setTimeout(function() {
            _this._hideOthersIcon();
        }, 500);
    },
    /***隐藏其他小图标***/
    _hideOthersIcon:function(){
        var by = _getBody();
        by.children("#k_edit_table_addbtn").hide();
        by.children("#k_edit_table_anchor").hide();   
    },
    /**
     * 删除某一段段落
     * **/
    _removeSection: function (section) {
        var _this = this;
        section.find("table").each(function () {
            _this._deleteTable($(this).attr("id"));
        });        
        section.remove();
        _this._hideOthersIconOnTimer();        
    },
    /**css修饰所选的元素
     * css可以是function，如果是function则需要设置this.cssing
     * **/
    css: function (css) {
        var isFn = typeof css === "function";
        var _this = this;
        //修饰前先计算出当前p段落的行高倍数
        var rates = {};
        var css2p = typeof this.ignorePele === "undefined";
        if (css["font-size"] && css2p) {
            this.foreachPTargets(function (p, i) {
                if (!p.hasClass("_exclude_")) {
                    var r = _this._getLineHeightRate(p);
                    rates[i] = r;
                }
            });
        }
        this.foreachTargets(function ($t, i) {
            if (!$t.hasClass("_exclude_")) {
                if (isFn) {
                    css($t);
                } else {
                    $t.css(css);
                    $t.children("a").css(css); 
                }
            }
        });
        //更新p段落line-height
        if (css["font-size"] && css2p) {
            this.foreachPTargets(function (p, i) {
                if (!p.hasClass("_exclude_")) {
                    var maxFs = _this._getParagraphMaxFontSize(p);
                    var r = rates[i];
                    var line_height = (r * maxFs) + "px";
                    p.css("line-height", line_height);
                    p.find("li").css("line-height", line_height);
                }
            });
        }
        //记录当前正在执行的css修饰，afterExecute清理this.cssing
        if (!isFn) {
            this.cssing = css;
        }
    },
    /**
     * 根据名称获取当前的css值，如果css不一样，返回undefined，否则返回css值
     * //需要对text-decoration 进行处理 剔除solid rgb(102, 102, 102)
     * **/
    getCurrentCssValue: function (cssName) {
        var cssValue;
        this.foreachTargets(function ($t, i) {
            if (!$t.hasClass("_exclude_")) {
                var val = $t.css(cssName);
                if (cssName === "text-decoration") {
                    if (val) {
                        if (val.indexOf("underline") > -1) {
                            val = "underline";
                        }
                        if (val.indexOf("line-through") > -1) {
                            val = "line-through";
                        }
                    }
                }
                if (i === 0) {
                    cssValue = val;
                } else if (cssValue !== val) {
                    cssValue = undefined;
                    return false;
                }
            }
        });
        return cssValue;
    },
    /**
     * 获取ele中第一个子元素的fontSize
     * ***/
    _getFirstCharFontSize: function (ele) {
        var firstCharSize = parseFloat(ele.css("font-size").replace("px", ""));
        var firstEle = ele.children().first();
        var tmp = firstEle.css("font-size");
        if (tmp) {
            tmp = parseFloat(tmp.replace("px", ""));
            if (tmp > firstCharSize) {
                firstCharSize = tmp;
            }
        }
        if (firstEle.children().length > 0 && firstEle[0].previousSibling === null) {
            firstCharSize = this._getFirstCharFontSize(firstEle.children().first());
        }
        return firstCharSize;
    },
    /**
     * 获取ele中第一个子元素的fontSize 
     * 内部调用_getFirstCharFontSize
     * 小于14则返回14
     * ***/
    getFirstCharFontSize: function (ele) {
        var fs = this._getFirstCharFontSize(ele);
        if (fs > 14) {
            return fs;
        }
        return 14;
    },
    /***实现选区实时颜色反馈显示***/
    changeSelectionColor: function (cssName, cssValue) {
        var style = '.k_edit_input_filed *::selection ,.k_editor_float_input  *::selection{' + cssName + ':' + cssValue + '}' +
            '.k_edit_input_filed *::-moz-selection ,.k_editor_float_input  *::selection{' + cssName + ':' + cssValue + '}' +
            '.k_edit_input_filed *::-webkit-selection ,.k_editor_float_input  *::selection{' + cssName + ':' + cssValue + '}';
        head.children("#_selection_style").remove();
        head.append("<style id='_selection_style'>" + style + "</style>");
    },
    /***
     * 
     * 将dom range提取到{
     *      rangeInfo = {
            startContainerId: startContainerId,
            endContainerId: endContainerId,
            startOffset: this.range.startOffset,
            endOffset: this.range.endOffset
        }
    * ***/
    _getRangeInfo: function () {
        var startContainerId = this.range.startContainer.parentNode.id;
        var endContainerId = this.range.endContainer.parentNode.id;
        var rangeInfo = {
            startContainerId: startContainerId,
            endContainerId: endContainerId,
            startOffset: this.range.startOffset,
            endOffset: this.range.endOffset
        };
        return rangeInfo;
    },
    /**创建\u200B 空文本节点**/
    _createEmptyTextNode: function () {
        var textNode = document.createTextNode("\u200B");
        return textNode;
    },
    /**
     * 在元素前后插入空\u200B字符
     * targetNode：待插入的目标节点
     * isBefore:前插入
     * **/
    _insertEmptyTextNode: function (targetNode, isBefore) {
        var txtNode = this._createEmptyTextNode();
        var parent = targetNode.parentNode;
        if (isBefore) {
            parent.insertBefore(txtNode, targetNode); //将b2插入到div2中的span2前面
        } else {
            if (parent.lastChild === targetNode) {
                parent.appendChild(txtNode);
            } else {
                parent.insertBefore(txtNode, targetNode.nextSibling);
            }
        }
    },
    /** 创建 默认style的 span***/
    _getSpan: function () {
        return $("<span style='" + eConfig.defaultStyle + "' id='" + getUUID() + "'>\u200B</span>");
    },
    /***
     * 设置段落移动
     * ***/
    setSectionMove: function () {
        var _this = this;
        var elArray = [];
        var el = this.startPElement;
        while (el.length > 0) {
            elArray.push(el);
            if (el[0] === this.endPElement[0]) {
                break;
            }
            el = el.next();
        }
        this._setMovingTargets(elArray, false);
    },
    /**
     * 设置移动目标eles = [jq1,jq2] / image 段落元素
     * ***/
    _setMovingTargets: function (eles, isImage, callFn) {        
       // console.log("_setMovingTargets >>>>>>>>");
        if (this.$input.hasClass("k_editor_float_input")) {
            return;
        }
        this.movingTargets = eles;
        this.isMovingImage = isImage;
        var firstEl;
        if (isImage) {
            firstEl = eles;
            var pEle = firstEl.parent();
            while (pEle.length > 0) {
                if (pEle[0].tagName === "DIV") {
                    break;
                }
                pEle = pEle.parent();
            }
            this.moveSrcPele = pEle;
        } else {
            firstEl = eles[0];
            this.moveSrcPele = firstEl;
        }
        //被移动目标所在的段落，及前一个段落
        var prevEl = this.moveSrcPele.prev();
        if (prevEl.length > 0) {
            this.moveSrcBeforePele = prevEl;
        }
        var pos = firstEl.position();
        var scrollTop = this.$inputWrap.scrollTop();
        var top = pos.top + scrollTop;
        var left = pos.left;
        var _this = this;
        _this.onMvAcnClick = callFn;
        if (!this.movingAcn) {
            this.movingAcn = $("<div title='" + eConfig.label.move + "' style='-moz-border-radius:10px;-webkit-border-radius:10px;border-radius:10px;border:1px solid #21F200;position:absolute;z-index:2147483647;left:" + left + "px;top:" + top + "px;padding:0 3px;cursor:move;'><i style='font-weight:bold;font-size:18px;' class='fa fa-move'></i></div>").appendTo(this.$inputWrap);
            this.movingAcn.draggable({
                cursor: 'move',
                onDragReady: function () {
                    _this.movingScroll = false;
                    if (typeof _this.onMvAcnClick === "function") {
                        _this.onMvAcnClick();
                    }
                    return true;
                },
                onStartDrag: function (args) { //开始拖动
                    scrollTop = _this.$inputWrap.scrollTop();
                    _this.movingScroll = true;
                    var state = args.state;
                    var data = state._data;
                    data.left = data.left + 22;
                    data.startLeft = data.startLeft + 22;
                    _this.movingAcn.css("left", data.left);                   
                    var ancStyle = _this._getCopyStyle(_this.movingAcn);
                    var floatPos = { top: parseFloat(ancStyle.top.replace("px", "")), left: parseFloat(ancStyle.left.replace("px", "")) + 26 };
                    _this.movingCopy = $("<div class='k_box_shadow' style='filter: alpha(opacity=80);-moz-opacity: 0.8;-khtml-opacity: 0.8;opacity:0.8;z-index:2147483645;position:absolute;top:" + floatPos.top + ";left:" + floatPos.left + "px'></div>");
                    if (_this.isMovingImage) {//移动图片
                        var w = _this.movingTargets.width();
                        var h = _this.movingTargets.height();
                        _this.movingCopy.css({width:w,height:h});
                        var copyImg = _this.movingTargets.clone();
                        var _f = _this.movingTargets.offset();
                         /**修复图片被浏览器默认拖动机制触发的bug***/
                        _this.imgMask = $("<div style='position:absolute;z-index:2147483600;width:"+(w + 5)+"px;height:"+(h + 5)+"px;top:"+(_f.top - 2)+"px;left:"+(_f.left - 2)+"px;'></div>").appendTo( _getBody() );
                        _this.movingCopy.append("<div style='position:absolute;z-index:2147483646;width:100%;height:100%;'></div>");
                        _this.movingCopy.prepend(copyImg.css({"position":"absolute","margin":0,"z-index":"2147483645","float":"none"})).appendTo(_this.$inputWrap);
                        //console.log("移动图片 >>>>>> 移动图片");                        
                    } else {//移动段落
                        for (var i = 0, len = _this.movingTargets.length; i < len; ++i) {
                            _this.movingCopy.append(_this.movingTargets[i].clone());
                        }
                        _this.movingCopy.appendTo(_this.$inputWrap);
                    }
                    _this.removeSectionResizeBar();  
                    if (_this.resizeBox) {
                        _this.resizeBox.unbind();                     
                    }                  
                },
                onMouseUp: function () {
                    setTimeout(function () {
                        _this.movingTargets = undefined;
                        _this.movingScroll = false;
                        _this.moveSrcBeforePele = undefined;
                        _this.moveSrcPele = undefined;
                        _this.insertAfterTarget = undefined;
                    }, 200);
                },
                onDrag: function (args) {
                    var state = args.state;
                    var data = state._data;
                    _this.movingCopy.css({ top: data.top, left: data.left + 18 });
                },
                onStopDrag: function (args) {                    
                    if(_this.imgMask){
                        _this.imgMask.remove();
                        _this.imgMask = undefined;
                    }                   
                    _this.movingAcn.hide();
                    _this.movingCopy.remove();
                    if (_this.insertAfterTarget) {
                        if (_this.insertLine) {
                            _this.insertLine.remove();
                            _this.insertLine = undefined;
                        }
                        if (_this.isMovingImage) {//如果是图片                                  
                            var newpele = _this.insertPElement(_this.insertAfterTarget);
                            var $img = _this.movingTargets;
                            var imgPt = $img.parent();
                            while (imgPt.length > 0) {
                                if (imgPt[0].tagName === "DIV") {
                                    break;
                                }
                                imgPt = imgPt.parent();
                            }
                            var float = _this._getCopyStyle($img).float;
                            if (float) {//浮动图片
                                newpele.addClass("clearfix");
                                $img.detach().appendTo(newpele);
                                _this._getSpan().insertAfter($img);
                            }
                            if (_this.isEmptySectionFn(imgPt)) {
                                imgPt.detach();
                            } else {
                                imgPt.removeClass("clearfix");
                            }
                        } else {//选择的段落
                            var tmpEl, targetEl = _this.insertAfterTarget;
                            for (var i = 0, len = _this.movingTargets.length; i < len; ++i) {
                                tmpEl = _this.movingTargets[i].detach();
                                targetEl = tmpEl.insertAfter(targetEl);
                            }
                            if(tmpEl.next("._section_div_").length === 0){
                                targetEl = _this.createPElement().insertAfter(tmpEl);
                            }
                            _this.moveToEnd(targetEl);
                        }
                    }
                    _this.insertAfterTarget = undefined;
                    _this.movingTargets = undefined;
                    _this.movingScroll = false;
                    _this.moveSrcBeforePele = undefined;
                    _this.moveSrcPele = undefined;    
                    if(_this.insertLine){
                        _this.insertLine.remove();
                    }             
                }
            });
        } else {
            this.movingAcn.css({ "top": top, "left": left }).show();
        }
    },
    /****
    * 创建当前窗口需要用到的颜色控件，绑定到窗口中
    * ***/
    _createWindowColorPicker: function () {
        if (this[this.windowName] && !this[this.windowName].data("colorPicker")) {
            var pick = new $B.ColorPicker(undefined, {
                update2Target: true,
                showCaret: false
            }).setValue("#A9CADD");
            pick["name"] = "window ColorPicker";
            this[this.windowName].data("colorPicker", pick);
        }
    },
    /**
    * 获取空的p段落用于插入视频、表格、代码
    * ***/
    _getInsertP: function () {
        var targetP;
        this._getRangeSections(function (p) {
            targetP = p;
        });
        var txt = targetP.text().replace(/\u200B/g,"");
        var insertTag;
        if (txt === "" || txt === "\u200B") {
            insertTag = targetP;
        } else {
            var $p = this.createPElement();
            insertTag = $p.insertAfter(targetP);
        }
        return insertTag;
    },
    /**在文本/curentPelement后面插入段落,当存在curentPelement，则插入curentPelement之后
        * return 新建的p
        * **/
    insertPElement: function (curentPelement) {
        var $p = this.createPElement();
        if (curentPelement) {
            $p.insertAfter(curentPelement);
        } else {
            $p.appendTo(this.$input);
        }
        this.moveToEnd($p);
        this.saveUserRange();
        return $p;
    },
    /**获取行高比**/
    _getLineHeightRate: function (pEl) {
        var fs = this._getParagraphMaxFontSize(pEl);
        var lineHeight = parseFloat(pEl.css("line-height").replace("px", ""));
        var rate = lineHeight / fs;
        return rate;
    },
    /**更新行高**/
    _updateParagraphLineHeight: function (pEl, lineHeightRate) {
        var fs = this._getParagraphMaxFontSize(pEl);
        var lineHeight = fs * lineHeightRate;
        pEl.css("line-height", lineHeight + "px");
    },
    /**获取段落内最大字体**/
    _getParagraphMaxFontSize: function (pEl) {
        if(pEl.length === 0){
            return 14;
        }
        var maxFontSize = 0;
        function _loopChild(el) {
            var maxfs = parseFloat(pEl.css("font-size").replace("px", ""));
            if (maxfs > maxFontSize) {
                maxFontSize = maxfs;
            }
            el.children().each(function () {
                var $c = $(this);
                var fs = parseFloat($c.css("font-size").replace("px", ""));
                if (fs > maxFontSize) {
                    maxFontSize = fs;
                }
                $c.children().each(function () {
                    _loopChild($(this));
                });
            });
        }
        _loopChild(pEl);
        return maxFontSize;
    },
    /**将鼠标移动到最后，并调用setCrossRange触发保持更新当前range
     * @param jqElement jq对象
     * **/
    moveToEnd: function (jqElement) {
        //找到最后一个文本节点
        try{
            var lastTextNode = this.getEleLastTextNode(jqElement);
            this.setCrossRange(lastTextNode, lastTextNode, lastTextNode.length, lastTextNode.length);
        }catch(ex){
            console.log("moveToEnd is exception");
        }        
    },
    /**
     * 移动到目标的开始位置
     * ***/
    moveToStart: function (jqElement) {
        var lastTextNode = this.getEleLastTextNode(jqElement);
        this.setCrossRange(lastTextNode, lastTextNode, 0, 0);
    },
    /**
     * 添加节点到targets中
     * isLoopChild是否包含子节点
     * **/
    _putNodeToTargets: function (jqNode, isLoopChild) {
        var _this = this;
        if (jqNode.length > 0 && !jqNode.data(selectDataKey)) {
            var tagName = jqNode[0].tagName;
            if (elementToTargets[tagName]) {//检测是否允许设置到目标中
                this.painTargets.push(jqNode);
                jqNode.data(selectDataKey, true);
            }
            if (isLoopChild) {
                //递归子元素
                jqNode.children().each(function () {
                    _this._putNodeToTargets($(this), true);
                });
            }
        }
    },
    /**
     * 清空paintargets 元素标志
     * **/
    _clearDataKeys: function () {
        this.foreachTargets(function (t) {
            t.removeData(selectDataKey);
        });
    },
    /**将text用span包装**/
    _loopSpanWrapText: function (wrap) {
        var childNodes = wrap.childNodes;
        for (var i = 0, len = childNodes.length; i < len; ++i) {
            var node = childNodes[i];
            if (node.nodeType === 3) {//找到文本节点,并且需要包装,这里需要过滤 <span>\u200b<img>\u200b</span>
                var pNode = node.parentNode;
                if($(pNode).children("img").length > 0){//img标签 不做包装处理
                    continue;
                }
                var childrenLength = node.parentNode.children.length;
                if (childrenLength > 0 && pNode.childNodes.length > childrenLength) {
                    var id = getUUID();
                    var html = "<span style='" + eConfig.defaultStyle + "' id='" + id + "'>" + node.nodeValue + "</span>";
                    var nextSibling = node.nextSibling;
                    if (nextSibling) {
                        $(html).insertBefore($(nextSibling));
                    } else {
                        $(html).insertAfter($(node.previousSibling));
                    }
                    node.parentNode.removeChild(node);
                    this.isNeedToReplace = true;
                }
            } else { //标签节点，继续递归
                this._loopSpanWrapText(node);
            }
        }
    },
    /***清理p标签下无用的span标签***/
    _getUselessSpan: function (ele) {
        var _this = this;
        for (var i = 0, len = ele.children.length; i < len; ++i) {
            var node = ele.children[i];
            //有子元素，并且没有任何属性则说明这是个无用的span
            if (node.children.length > 0) {
                if (node.attributes.length === 0) {
                    this.uselessSpan.push(node);
                }
            }
            _this._getUselessSpan(node);
        }
    },
    /***
     * 采用DocumentFragment避免解析过程中触发页面渲染
     * 利用span包装所有的text文本
     * pElement p段落标签
     * ***/
    _spanWrap2Text: function (pElement) {
        //跳过代码块
        var childrens = pElement.children();
        if (childrens.length < 2 && childrens.children("pre").length > 0) {//代码块
            return;
        }
        if(childrens.first()[0].tagName === "PRE"){//视频
            return;
        }
        //console.log("_spanWrap2Text >>>> ");
        var newFrag = document.createDocumentFragment();
        newFrag.appendChild(document.createElement("div"));
        var wrap = newFrag.firstChild;
        wrap.innerHTML = pElement[0].outerHTML;
        var ele = wrap.firstChild;
        this.isNeedToReplace = false;
        this._loopSpanWrapText(ele);
        this.uselessSpan = [];
        this._getUselessSpan(ele);
        for (var i = 0, len = this.uselessSpan.length; i < len; ++i) {
            var delSpan = $(this.uselessSpan[i]);
            delSpan.children().remove().insertAfter($(delSpan));
            delSpan.remove();
            this.isNeedToReplace = true;
        }
        if (this.isNeedToReplace) {
            var style = this._getCopyStyle(pElement);
            $(wrap).children().children().each(function () {
                $(this).css(style);
            });
            pElement.html(wrap.children[0].innerHTML);
        }
    },
    /**
     * 查询node节点所在的段落元素
     * **/
    _findNodePElement: function (node) {
        var parent = node;
        while (true) {
            if (parent.length === 0 || (parent[0].tagName === sectionTag && parent.hasClass("_section_div_")))  {
                break;
            }
            parent = parent.parent();
        }
        return parent;
    },
    /**
     * child是否被parentEl包含
     * 同一个元素 为true
     * **/
    _contains: function (parentEl, child) {
        var isContains = false;
        if (parentEl[0] === child[0]) {
            return true;
        }
        var pEl = child.parent();
        while (pEl[0].tagName !== sectionTag) {
            if (pEl[0] === parentEl[0]) {
                isContains = true;
                break;
            }
            pEl = pEl.parent();
        }
        return isContains;
    },
    /**
     * 将文本分割为span标签包装/n
     * range里面的startOffset，endOffset/n
     * splitCheck:分割检查，传值则说明不处理全选的情况,全选时候直接返回“”
     * **/
    _text2spanWrap: function (text, startOffset, endOffset, splitCheck) {
        if (text === '\u200B' || text === "") {
            return "";
        }
        if (splitCheck) {
            var offSetCount = endOffset - startOffset;
            if (offSetCount === text.length) {
                return "";
            }
        }
        //分割为三个组
        var array1 = [],
            array2 = [],
            array3 = [],
            txt = '',
            startIndex = startOffset,
            endIndex = endOffset;
        var span1 = $("<span style='" + eConfig.defaultStyle + "' id='" + getUUID() + "'/>");
        var span2 = $("<span class='_wrap_target_node_' style='" + eConfig.defaultStyle + "' id='" + getUUID() + "'>\u200B</span>");
        var span3 = $("<span style='" + eConfig.defaultStyle + "' id='" + getUUID() + "'/>");
        for (var i = 0, len = text.length; i < len; ++i) {
            txt = text[i];
            if (txt === '\u200B') {
                continue;
            }
            if (i < startIndex) {
                array1.push(txt);
            } else if (i >= startIndex && i < endIndex) {
                array2.push(txt);
            } else {
                array3.push(txt);
            }
        }
        var html1 = array1.join("").replace(/<span\s+\S+\s*><\/span>/g, "");
        var html2 = array2.join("");
        var html3 = array3.join("").replace(/<span\s+\S+\s*><\/span>/g, "");
        var tmp = [];
        if (html1 !== "") {
            span1.text(html1);
            tmp.push(span1[0].outerHTML);
        }
        if (html2 !== "") {
            span2.text(html2);
        }
        tmp.push(span2[0].outerHTML);
        if (html3 !== "") {
            span3.text(html3);
            tmp.push(span3[0].outerHTML);
        }
        return tmp.join("");
    },
    /**将ele元素的style属性创建为对象副本返回,用于合并到子元素样式
     * 对td / p 进行过滤不需要设置到子元素的样式
     * **/
    _getCopyStyle: function (ele) {
        var cssObj = this._style2CssObject(ele);
        if (ele[0].tagName === "TD") {
            cssObj = {
                "background-color": cssObj["background-color"],
                "color": cssObj["color"],
                "font-weight": cssObj["font-weight"],
                "font-style": cssObj["font-style"],
                "text-decoration": cssObj["text-decoration"],
                "font-family": cssObj["font-family"],
                "font-size": cssObj["font-size"],
                "letter-spacing": cssObj["letter-spacing"],
            };
        } else if (ele[0].tagName === "DIV") {
            delete cssObj["text-indent"];
            delete cssObj["line-height"];
            delete cssObj["width"];
            delete cssObj["padding-left"];
            delete cssObj["padding-right"];
            delete cssObj["margin-top"];
            delete cssObj["margin-bottom"];
        }
        return cssObj;
    },
    /***
     * 提取style 为 json对象返回,用于全量复用
     * ***/
    _style2CssObject: function (ele, notExt) {
        var style = ele.attr("style");
        var styles = {};
        if (style) {
            var tmpArr = style.split(";");
            for (var i = 0, len = tmpArr.length; i < len; ++i) {
                if (tmpArr[i] !== "") {
                    var s = tmpArr[i].split(":");
                    var key = $.trim(s[0]);
                    var val = $.trim(s[1]);
                    if (notExt || !extCopyCfg[key]) {
                        styles[key] = val;
                    }
                }
            }
        }
        return styles;
    },
    /***清空painTargets 
     * 但不影响range
     * ***/
    _removePainTargets: function () {
        this._clearDataKeys();
        this.painTargets = [];
    },
    /***
     * 清空选区range记录
     * ***/
    _clearRangeRecord: function () {
        this._removePainTargets();
        this.isFindedStartNode = false;
        this.isFindedEndNode = false;
        this.startPElement = undefined;
        this.endPElement = undefined;
        head.children("#_selection_style").remove();
    },
    /**如果存在选区则提取修饰目标，否则不提取修饰目标
     * 先_removePainTargets后再setPaintTarget
     * **/
    createTargetsByRange: function () {
        if (this.range && !this.range.collapsed) {
            this._removePainTargets();
            this.setPaintTarget();
        }
    },
    /**
     * 获取开始/结束目标节点
     * **/
    _getStartEndtNode: function (container, isStart, isCross) {
        var tag, i, len, tempNode;
        if (container.nodeType === 3) {
            var wrap = $(container.parentNode);
            var nodeValue = container.nodeValue;
            var isSelectAll = false;
            var endIndex;
            var startIndex;
            if (isCross) { //跨标签选择
                if (isStart) { //解析的是开始节点
                    isSelectAll = this.startOffset === 0 && container.parentNode.nodeName !== sectionTag && container.parentNode.children.length === 0;
                    startIndex = this.startOffset;
                    endIndex = nodeValue.length; //- 1;
                } else { //解析的是结束节点
                    isSelectAll = nodeValue.length === this.endOffset && container.parentNode.nodeName !== sectionTag && container.parentNode.children.length === 0;
                    startIndex = 0;
                    endIndex = this.endOffset;
                }
            } else {
                startIndex = this.startOffset;
                endIndex = this.endOffset;
                //判断是否是全选
                isSelectAll = startIndex === 0 && nodeValue.length === this.endOffset && container.parentNode.nodeName !== sectionTag && container.parentNode.children.length === 0;
            }
            //var i ,len;
            if (isSelectAll) { //标签被全选
                tag = wrap;
            } else {
                var style;
                var _html = this._text2spanWrap(nodeValue, startIndex, endIndex);
                var $html = $(_html);
                if (wrap.children().length === 0) { //纯文本节点
                    style = this._getCopyStyle(wrap);
                    $html.css(style);
                    if (wrap[0].tagName === "SPAN") {
                        // for(i = 0 ,len = spansArray.length ; i < len ; ++i){
                        //     spansArray[i].css(style);
                        // }
                        $html.insertAfter(wrap);
                        // var removeNodeId = wrap.attr("id");
                        wrap.remove();
                    } else {
                        wrap.html($html);
                    }
                    for (i = 0, len = $html.length; i < len; ++i) {
                        tempNode = $($html[i]);
                        if (tempNode.hasClass("_wrap_target_node_")) {
                            tag = tempNode;
                            break;
                        }
                    }
                } else {
                    var nextSibling = container.nextSibling;
                    var retTags, $sibling;
                    if (nextSibling) {
                        $sibling = $(nextSibling);
                        style = this._getCopyStyle($sibling.parent());
                        retTags = $html.css(style).insertBefore($sibling);
                    } else {
                        $sibling = $(container.previousSibling);
                        style = this._getCopyStyle($sibling.parent());
                        retTags = $html.css(style).insertAfter($sibling);
                    }
                    container.parentNode.removeChild(container);
                    tag = retTags.filter("._wrap_target_node_");
                }
            }
        } else { //如果容器的标签节点                
            if (container.childNodes.length === 1) {
                tag = $(container);
            } else {
                tag = $(container);
            }
        }
        return tag.removeClass("_wrap_target_node_");
    },
    /**将p段落的所有子span元素放到修饰数组中**/
    _putPelChild2Targets: function (pEl) {
        var _this = this;
        pEl.find("span").each(function () {
            _this._putNodeToTargets($(this), false);
        });
    },
    /***将父元素的nextAll、prevAll里面的span放到修饰数组中
     * 应对 开始、结束标签在li、td里面的情况
     * ***/
    _putParentEl2Targets: function (parentEl, isStart) {
        if (parentEl.length === 0 || parentEl[0].tagName === "DIV") {
            return;
        }
        var _this = this;
        var isGo = true;
        if (isStart) {
            parentEl.nextAll().each(function () {
                if (_this._endNodeParent[0] !== this) {
                    _this._putNodeToTargets($(this), true);
                } else {
                    isGo = false;
                    return false;
                }
            });
        } else {
            parentEl.prevAll().each(function () {
                if (_this._startNodeParent[0] !== this) {
                    _this._putNodeToTargets($(this), true);
                } else {
                    isGo = false;
                    return false;
                }
            });
        }
        if (isGo) {
            this._putParentEl2Targets(parentEl.parent(), isStart);
        }
    },
    /**根据光标/选区设置修饰目标,不包含段落标签
     * 设置成功：return true / false
     * **/
    setPaintTarget: function () {
        var _this = this;
        var range = this.range;
        if (!range) {
            return false;
        }
        //避免拖动过程中重新设置 painTargets
        if (this.painTargets.length > 0) {
            var domRange = this.getDomRange();
            if (!domRange.collapsed) { //查看当前保存的选区和dom的一致
                if (domRange.startContainer === range.startContainer && domRange.endContainer === range.endContainer) {
                    return true;
                }
            } else {
                this.clearUserRange();
            }
        }
        if (!range.collapsed) { //如果选择了内容
            var startTag = null,
                endTag = null;
            this.startOffset = range.startOffset;
            this.endOffset = range.endOffset;
            this.endContainer = range.endContainer;
            this.startContainer = range.startContainer;
            var isCross = this.startContainer !== this.endContainer;
            if (isCross) { //跨标签选择
                //开始标签
                startTag = this._getStartEndtNode(this.startContainer, true, isCross);
                //结束标签
                endTag = this._getStartEndtNode(this.endContainer, false, isCross);
                this.startPElement = this._findNodePElement(startTag);
                this.endPElement = this._findNodePElement(endTag);
            } else { //选区同一个标签，开始节点，结束节点是一致的
                startTag = this._getStartEndtNode(this.startContainer, true, isCross);
                endTag = startTag;
                this.startPElement = this._findNodePElement(startTag);
                this.endPElement = this.startPElement;
            }
            //打上标签ID      
            startTag.attr("class", "_k_edit_start_node_");
            if (isCross) {
                endTag.attr("class", "_k_edit_end_node_");
            }
            /***
             * 处理p标签里面混合标签、文字的情况
             * ***/
            var startPEle = this.startPElement;
            while (startPEle.length > 0) {
                var childs = startPEle.children();
                if (childs.length === 1 && childs.first()[0].tagName !== "TABLE") {
                    this._spanWrap2Text(startPEle);
                }
                if (startPEle[0] === this.endPElement[0]) {
                    break;
                }
                startPEle = startPEle.next();
            }
            startTag = this.startPElement.find("._k_edit_start_node_").removeClass("_k_edit_start_node_");
            if (isCross) {
                endTag = this.endPElement.find("._k_edit_end_node_").removeClass("_k_edit_end_node_");
            } else {
                endTag = startTag;
            }
            if (startTag.length === 0 && endTag.length > 0) {
                startTag = endTag;
            }
            if (endTag.length === 0 && startTag.length > 0) {
                endTag = startTag;
            }
            if (startTag.length === 0 && endTag.length === 0) {
                return false;
            }
            //做一次span嵌套清理
            var tmpPel = this.startPElement;
            while (tmpPel.length > 0) {
                this._fixNestSpan(tmpPel);
                tmpPel = tmpPel.next();
                if (tmpPel[0] === this.endPElement[0]) {
                    break;
                }
            }
            //恢复选区 	并将修饰目标放到Targets中			
            this.createCrossRange(startTag, endTag);
            this._putNodeToTargets(startTag, true);
            //startTag \ endTag肯定是span,span的parent可能是div、li、td
            //用于 _putParentEl2Targets 
            this._startNodeParent = startTag.parent();
            var tagName;
            while (this._startNodeParent.length > 0) {
                tagName = this._startNodeParent[0].tagName;
                if (tagName === "DIV" || tagName === "LI" || tagName === "TD" || tagName === "TR" || tagName === "P") {
                    break;
                }
                this._startNodeParent = this._startNodeParent.parent();
            }
            this._endNodeParent = endTag.parent();
            while (this._endNodeParent.length > 0) {
                tagName = this._endNodeParent[0].tagName;
                if (tagName === "DIV" || tagName === "LI" || tagName === "TD" || tagName === "TR" || tagName === "P") {
                    break;
                }
                this._endNodeParent = this._endNodeParent.parent();
            }
            if (isCross) {
                var nextEle = startTag.next();
                while (nextEle.length > 0 && nextEle[0] !== endTag[0]) {
                    this._putNodeToTargets(nextEle, false);
                    nextEle = nextEle.next();
                }
                if (this._startNodeParent[0] !== this._endNodeParent[0]) {
                    this._putParentEl2Targets(startTag.parent(), true);
                }
            }
            //跨段落
            if (this.startPElement[0] !== this.endPElement[0]) {
                tmpPel = this.startPElement.next();
                while (tmpPel.length > 0) {
                    if (tmpPel[0] === this.endPElement[0]) {
                        break;
                    }
                    this._putPelChild2Targets(tmpPel);
                    tmpPel = tmpPel.next();
                }
            }
            //设置结束标签
            if (this._startNodeParent[0] !== this._endNodeParent[0]) {
                this._putParentEl2Targets(endTag.parent(), false);
                var preEles = endTag.prevAll();
                preEles.each(function () {
                    _this._putNodeToTargets($(this), false);
                });
            }
            this._putNodeToTargets(endTag, true);
        } else { //如果没有选择内容，将提取光标所在的元素，及开始段落，结束段落
            var ancContainer = range.commonAncestorContainer;
            if (ancContainer.nodeType === 3) {
                ancContainer = $(ancContainer.parentNode);
            } else {
                ancContainer = $(ancContainer);
            }
            this.painTargets.push(ancContainer);
            this.startPElement = this._findNodePElement(ancContainer);
            this.endPElement = this.startPElement;
        }
        this._startNodeParent = undefined;
        this._endNodeParent = undefined;
        clearTimeout(this.clearTargetdataflagTimer);
        this.clearTargetdataflagTimer = setTimeout(function () {
            _this._clearDataKeys();
        }, 500);
        return true;
    },
    /**修正段落内的span嵌套span***/
    _fixNestSpan: function (pElement) {
        //console.log("_fixNestSpan  >>>>>>> _fixNestSpan");
        var _this = this;
        var clearFn = function () {
            var tmpEl = $(this);
            var tmpChild = tmpEl.children("span");
            if (tmpChild.length > 0) {
                var pStyle = _this._getCopyStyle(tmpEl);
                tmpChild.each(function () {
                    var $c = $(this);
                    var cStyle = _this._getCopyStyle($c);
                    $c.css($.extend(pStyle, cStyle));
                });
                tmpChild.detach().insertAfter(tmpEl);
                tmpEl.remove();
            }
        };
        pElement.children("span").each(clearFn);
    },
    /***
     * 段落鼠标enter事件
     * **/
    bindSectionElEvent: function (e) {
        var _this = e.data._this;
        if (_this.movingScroll) {
            if (_this.moveSrcPele[0] !== this && (!_this.moveSrcBeforePele || _this.moveSrcBeforePele[0] !== this)) {               
                var el = $(this);
                var pos = el.position();
                var scrollTop = _this.$inputWrap.scrollTop();
                var mvData = _this.movingAcn.data('_mvdata');
                var acnPos, cpPos, diff, go2Upate = false;
                if (pos.top < 0) {
                    go2Upate = true;
                    var prev = el.prev();
                    if (prev.length > 0) {
                        pos = prev.position();
                    }
                    diff = pos.top;
                } else {
                    var height = _this.$inputWrap.height();
                    var pHeight = el.height();
                    var maxTop = pHeight + pos.top;
                    diff = maxTop - height;
                    if (diff > 0) {
                        go2Upate = true;
                        var nextEl = el.next();
                        if (nextEl.length > 0) {
                            diff = diff + 22;
                        }
                    }
                }
                if (go2Upate) {
                    scrollTop = scrollTop + diff;
                    _this.$inputWrap.scrollTop(scrollTop);
                    //调整scrolltop后 修改位置                        
                    mvData.top = mvData.top + diff;
                    mvData.startTop = mvData.startTop + diff;
                    acnPos = _this.movingAcn.position();
                    cpPos = _this.movingCopy.position();
                    _this.movingAcn.css("top", acnPos.top + diff);
                    _this.movingCopy.css("top", cpPos.top + diff);
                }
                if (!_this.insertLine) {
                    _this.insertLine = $("<div class='clearfix' style='height:12px;position:relative;'><i style='z-index:2;font-weight:bold;font-size:10px;color:#21F200;position:absolute;top:0;left:0;z-index:1;' class='fa fa-right-open-2'></i><div class='k_box_size' style='border-left:4px solid #fff;top:5px;height:2px;background:#21F200;float:left;width:100%;position:absolute;'></div></div>");
                } else {
                    _this.insertLine.remove();
                }
                _this.insertLine.insertAfter(el).show();
                _this.insertAfterTarget = el;
            } else {
                _this.insertAfterTarget = undefined;
                if(_this.moveSrcPele[0] === this){
                    if(_this.insertLine){
                        _this.insertLine.hide();
                    }
                   //console.log("移动到原来的位置》》》》");
                }
            }
        }
    },
    /**
     * 设置数据
     * **/
    setContent: function (datas) {
        if (typeof datas === "string") {
            datas = $(datas);
        }
        var _this = this;
        //处理浮动文本、图片           
        var floatTxt = $("<div></div>");
        var text = $("<div></div>");
        var videoPreArray = [];
        var i, len;
        for (i = 0, len = datas.length; i < len; ++i) {
            var tmp = datas[i];
            var $tmp = $(tmp);
            var pre = $tmp.children("pre");
            if (pre.length === 0) {
                $tmp.children("span").children("pre");
            }
            var html, $i;
            if (pre.length > 0) { // pre标签保持原样
                if (pre.hasClass('k_video_pre')) {
                    html = tmp.outerHTML.replace(/[\n\r]/g, "").replace(/>[\s]+</g, "><");
                    $i = $(html);//替换回车换行
                    pre = $i.children("pre");
                    videoPreArray.push(pre);
                } else {
                    var pId = pre.parent().attr("id");
                    pre.remove();
                    html = tmp.outerHTML.replace(/[\n\r]/g, "").replace(/>[\s]+</g, "><");
                    $i = $(html);//替换回车换行
                    $i.find("#" + pId).append(pre);
                }
            } else {
                //代码块场景 
                var allSpan = $tmp.children("span");
                var isCodePre = false; 
                if( allSpan.length < 4 && allSpan.children("pre").length > 0){
                    isCodePre = true;
                }
                html = tmp.outerHTML;
                if(!isCodePre){
                    html = html.replace(/[\n\r]/g, "").replace(/>[\s]+</g, "><");
                }               
                $i = $(html);//替换回车换行
            }
            if ($i.hasClass("_section_div_")) {
                text.append($i);
            } else if ($i.hasClass("k_edit_float_panel")) {
                floatTxt.append($i);
            }
        }
        var ps = text.children().remove();
        ps.appendTo(this.$input);
        this.buildObjectsEventsByTag(ps);
        var allPeles = this.$input.children();
        allPeles.bind("mouseenter", { "_this": this }, this.bindSectionElEvent);       
        var lastP = allPeles.last();
        var children = lastP.children();
        if (children.length === 1) {
            var name = children.first()[0].tagName;
            if (name === "IMG" || name === "TABLE") {
                lastP = this.insertPElement();
            }
        }        
        var floatPanels = floatTxt.children().remove();
        this.$inputWrap.append(floatPanels);
        floatPanels.each(function () {
            var $t = $(this);
            var inputWrap = _this._bindFloatPanelEvents($t);
            if (inputWrap) {
                var pres = inputWrap.children("div");
                _this.buildObjectsEventsByTag(pres);
                pres.children("pre").each(function () {
                    var $pre = $(this);
                    if ($pre.hasClass("k_video_pre")) {
                        videoPreArray.push($pre);
                    }
                });
            }
        });       
        setTimeout(function () {
            var firstPle = _this.$fixInput.children().first();
            if(firstPle.hasClass("_exclude_")){
                firstPle = firstPle.next();
                if(firstPle.length === 0 || firstPle[0].tagName === "IMG" || firstPle[0].tagName === "TABLE"){
                    firstPle = _this.insertPElement();
                }
            }           
            _this.moveToEnd(firstPle);
            var videoPre, videoOpt;
            for (i = 0, len = videoPreArray.length; i < len; ++i) {
                videoPre = videoPreArray[i];
                videoOpt = JSON.parse(videoPre.attr("data").replace(/&quot;/g, "\""));
                _this._createVideoPlayer(videoPre, videoOpt);
            }
            videoPreArray = undefined;
        }, 1);
    },
    /***
     * replace(/&lt;/g, "<").replace(/&gt;/g, ">")
     * decodeURIComponent
     * 后调用setContent
     * ***/
    setHtmlString: function (data) {
        var str = data.replace(/&lt;/g, "<").replace(/&gt;/g, ">");
        str = decodeURIComponent(str);
        this.setContent(str);
    },
    /**
     * 内容恢复后对table、a 、prev video标签进行对象创建，事件绑定
     * **/
    buildObjectsEventsByTag: function (wrap) {       
        if(wrap.length === 0){
            return;
        }
        var _this = this;
        //恢复表格
        var rebuildTableFn = function () {
            var tableTag = $(this);
            tableTag.css({
                "border-collapse": "collapse",
                "width": "auto",
                "height": "auto",
                "cursor": "default"
            });
            //初始化table
            tableTag.find("td.k_edit_selected_td_shadow").removeClass("k_edit_selected_td_shadow");
            var table = new Table(_this).initByJq(tableTag);
            _this.tables.push(table);
        };
        //恢复a标签
        var buildAFn = function () {
            _this._bindAEleEvents($(this));
        };
        //恢复image事件
        var buildImgFn = function () {
            _this._bindImageEvents($(this));
        };
        //代码块事件
        var buildCodeFn = function () {
            var $pre = $(this);
            if ($pre.hasClass("k_video_pre")) {
                _this._bindVideoEvents($pre);
            } else {
                _this._bindPreEvents($pre);
            }
        };
        //恢复重建事件
        wrap.each(function () {
            var div = $(this);
            if (div.hasClass("k_split_line")) {//恢复分割线事件
                _this._bindSplitLineEvent(div);
            } else {
                var tabs = div.children("table").each(rebuildTableFn);
                var as = div.find("a").each(buildAFn);
                var imgs = div.find("img").each(buildImgFn);
                if (tabs.length === 0 && as.length === 0 && imgs.length === 0) {
                    div.children("span").children("pre").each(buildCodeFn);
                    var pres = div.children("pre");
                    if (pres.length === 0) {
                        pres = div.children("pre");
                    }
                    pres.each(buildCodeFn);
                }
            }
        });
        //console.log("buildObjectsEventsByTag >>>>>>>> buildObjectsEventsByTag");
    },
    /**
     * dom转存html时候，处理视频容器
     * ***/
    _fixVideoHtml: function($el){
        if($el.length === 0){
            return ;
        }        
        var videoWrap = $el.children(".video-js");
        if (videoWrap.length > 0) {
            var video = videoWrap.children("video").remove();
            var videoId = video.attr("id").replace("_html5_api", "");
            video.attr("id", videoId).insertAfter(videoWrap);
            //补充上videojs的自动 data-setup
            var prop = $el.attr("data").replace(/&quot;/g, "\"");
            video.attr("data-setup", prop).addClass("video-js vjs-default-skin vjs-big-play-centered");
            videoWrap.remove();
        }
    },
    /***循环移除不需要的属性***/
    _loopElClearUnlegalAttr: function (el) { 
        var isVideoEl = !(el.nodeName !== "PRE" || (el.nodeName === "PRE" && ! $(el).hasClass("k_video_pre")));
        if(isVideoEl){
            this._fixVideoHtml($(el));
        }
        //this._removeUnlegalAttr(el); 
        //if (el.nodeName !== "PRE" || (el.nodeName === "PRE" && ! $(el).hasClass("k_video_pre"))) {            
            // for(var i = 0 ,len = el.children.length ; i < len ; ++i ){
            //     this._loopElClearUnlegalAttr(el.children[i]);
            // }
        // } else {//处理视频容器
        //    this._fixVideoHtml($(el));
        // }
    },
    /**
     * 获取数据
     * urlEncode:是否url 编码
     * **/
    getContent: function (urlEncode) {
        //var startDate = new Date();
        var res,
            floatHtmls ;
        if(this.currentHTML){
            res = this.currentHTML;           
        }else{
            res = this.$fixInput.children().clone();
        }           
        if(this.currentFloatHTML){
            floatHtmls = this.currentFloatHTML;
        }else{
            floatHtmls = this.$inputWrap.children(".k_edit_float_panel").clone();
        }
        this._clearCurrentHtml();
        var html = [], phtml, tag, $tag,i = 0, len,id;       
        for (i = 0, len = res.length; i < len; ++i) {
            tag = res[i];
            $tag = $(tag);
            // id = $tag.attr("id");
            this._loopElClearUnlegalAttr(tag);
            if ($tag.hasClass("_section_div_close_title") && $tag.attr("closed_status")) {
                var closeCount = parseInt($tag.attr("closed_count"));
                var j = i, tmpTag;
                while (closeCount > 0) {
                    tmpTag = $(res[j + 1]);
                    j++;
                    closeCount--;
                    tmpTag.css("display", "none");
                }
            }
            phtml = tag.outerHTML.replace(/cursor:\s*((?!;).)+;/g, "");
            if (urlEncode) {
                phtml = encodeURIComponent(phtml);
            }
            html.push(phtml);
        }      
        var _this = this;
        //浮动文本 、图片
        for (i = 0, len = floatHtmls.length; i < len; ++i) {
            $tag = $(floatHtmls[i]);
            $tag.children(".k_editor_float_input").removeAttr("contenteditable");
            _this._loopElClearUnlegalAttr($tag[0]);
            phtml = $tag[0].outerHTML.replace(/cursor:\s*((?!;).)+;/g, "");
            if (urlEncode) {
                phtml = encodeURIComponent(phtml);
            }
            html.push(phtml);
        }
        // var endDate = new Date();
        // console.log("time " + (endDate - startDate));
        return html.join("");
    },    
    /**
     *清空用户选择的选区 
     **/
    clearUserRange: function (clearDom) {
        if (clearDom) {
            var selection = this.getDomSelection();
            try {
                selection.removeAllRanges();
            } catch (e) { }
        }
        this.range = undefined;
        this._clearRangeRecord();
    },
    /***
     *重建用户选区 
     *rangeInfo = {startContainerId,endContainerId, startOffset,endOffset}
     *当存在rangeInfo参数时候以rangeInfo创建选区
     *否则以this.range作为恢复记录（用于焦点变化的重建）
     ***/
    rebuildUserRange: function (rangeInfo) {
        try {
            if (rangeInfo) {
                var startContainerId = rangeInfo.startContainerId,
                    endContainerId = rangeInfo.endContainerId;
                var startContainer = this.$input.find("#" + startContainerId)[0];
                var endContainer = this.$input.find("#" + endContainerId)[0];
                startContainer = this.getEleFirstTextNode(startContainer);
                endContainer = this.getEleLastTextNode(endContainer);
                this.setCrossRange(startContainer, endContainer, rangeInfo.startOffset, rangeInfo.endOffset);
            } else {
                if (this.range) {
                    var selection = this.getDomSelection();
                    try {
                        selection.removeAllRanges();
                    } catch (e) { }
                    selection.addRange(this.range);
                }
            }
        } catch (ex) {
            console.log("rebuildUserRange error !");
        }
    },
    /**
     *保存当前dom中用户选择的选区 
     **/
    saveUserRange: function () {
        // console.log(" saveUserRange saveUserRange saveUserRange");
        var r = this.getDomRange();
        //修正startContainer、 endContainer不是textNode的情况
        if (!r) {
            return;
        }
        this.range = r;
    },
    /***获取container的文本节点，如果没有文本节点则补充上文本节点
     * 用于解析提取range中的开始、结束文本节点
     * ***/
    _getContainerTextNode: function (container, isEnd) {
        var child,$p;
        if (isEnd) {
            child = container.lastChild;
            if(child.nodeName === "IMG"){
                $p = $(child.parentElement);
                $p = this._getSpan().insertAfter($p);
                child =  $p[0].firstChild;
            }
        } else {
            child = container.firstChild;
            if(child.nodeName === "IMG"){
                $p = $(child.parentElement);
                $p = this._getSpan().insertBefore($p);
                child =  $p[0].firstChild;
            }
        }
        var parentNode;
        if (child) { //存在子节点
            if (child.nodeType === 1) { //子节点是非文本元素
                if (child.tagName === "BR") {
                    parentNode = child.parentNode;
                    parentNode.removeChild(child);
                    if (parentNode.tagName === "SPAN") {
                        child = $(parentNode).html("\u200B")[0].firstChild;
                    } else {
                        child = this._getSpan().appendTo($(parentNode))[0].firstChild;
                    }
                } else if (child.tagName === "TABLE") {//跳到第一个单元格
                    var firstTd = $(child).children("tbody").children().first().children().first();
                    child = this.getEleLastTextNode(firstTd);
                } else if (child.tagName !== "SPAN") { //如选择的是img/td/a标签
                    console.log("选区边界元素非span元素》》》》》》》》》》》》》》》》》》》》》！");
                } else {
                    child = child.firstChild;
                    if (child && child.nodeType !== 3) {
                        parentNode.removeChild(child);
                        child = $(parentNode).html("\u200B")[0].firstChild;
                    }
                }
            } else { //子节点是文本元素
                return child;
            }
        } else { //不存在子节点
            if (container.tagName === "DIV") {
                child = this._getSpan().appendTo($(container))[0].firstChild;
            } else {
                child = $(container).html("\u200B")[0].firstChild;
            }
        }
        return child;
    },
    /***提取dom的range，而且不做任何处理* **/
    _getDomRangeOnly: function () {
        var range;
        var seletionObj = this.getDomSelection();
        if (seletionObj.getRangeAt && seletionObj.rangeCount > 0) {
            range = seletionObj.getRangeAt(0);
        } else { // 老版本浏览器
            if (seletionObj.anchorNode) {
                range = document.createRange();
                range.setStart(seletionObj.anchorNode, seletionObj.anchorOffset);
                range.setEnd(seletionObj.focusNode, seletionObj.focusOffset);
            }
        }
        return range;
    },
    /***
     * 创建div 段落
     * **/
    createPElement: function () {
        var id = getUUID();
        var id2 = getUUID();
        var $p = $("<" + sectionTag + " id='" + id + "' class='_section_div_'><span style='" + eConfig.defaultStyle + "' id='" + id2 + "'>\u200B</span></" + sectionTag + ">");
        $p.css(eConfig.pElementCss);
        $p.bind("mouseenter", { "_this": this }, this.bindSectionElEvent);       
        return $p;
    },
    /***
     * 获取dom range，对startContainer、endContainer非文本节点进行修正
     * 返回的range，确保startContainer、endContainer是文本节点
     * isFixContainer:是否需要修正开始、结束节点为文本节点，默认true
     * 2019-06-26 修复开始、结束节点为img的场景bug
     * ***/
    getDomRange: function (isFixContainer) {
        var range = this._getDomRangeOnly();
        if (range) {
            try {
                //fix startContainer endContainer 保证这两个节点必须为文本节点
                var start = range.startContainer;
                var end = range.endContainer;
                var need2fix = false;
                var isFix = typeof isFixContainer === "undefined" ? true : isFixContainer;
                var firstChild = start,
                    lastChild = end,
                    startOffset, endOffset;
                if (start.nodeType === 1) {
                    if (isFix) {
                        need2fix = true;
                        if(start.nodeName === "IMG"){                            
                            firstChild = start.nextSibling;
                        }else{
                            firstChild = this._getContainerTextNode(start);
                        }
                        startOffset = 0;
                    }
                } else {
                    startOffset = range.startOffset;
                }
                if (end.nodeType === 1) {
                    if (isFix) {
                        if (start === end) {
                            lastChild = firstChild;
                        } else {
                            if(end.nodeName === "IMG"){                                
                                lastChild = end.previousSibling;
                            }else{
                                lastChild = this._getContainerTextNode(end, true);
                            }                            
                        }
                        need2fix = true;
                        endOffset = lastChild.nodeValue.length;
                    }
                } else {
                    endOffset = range.endOffset;
                }
                if (need2fix) { //需要修正
                    //console.log("需要修正 非文本节点");
                    if (firstChild === lastChild && startOffset === 0 && endOffset === 1) {
                        startOffset = 1;
                    }
                    range = this.setCrossRange(firstChild, lastChild, startOffset, endOffset);
                }
                //ie fix startContainer bug
                if (start.nodeType === 3 && !range.collapsed) {
                    if (range.startOffset === start.length) {
                        range = this.createCrossRange(end, end);
                    }
                }
                return range;
            } catch (ex) {
                return undefined;
            }
        }
    },
    /***
     *获取dom中选区 
     ***/
    getDomSelection: function () {
        var selection;
        if (window.getSelection) {
            selection = window.getSelection();
        } else if (document.selection) {
            selection = document.selection.createRange();
        }
        return selection;
    },
    /**
     * 获取ele元素下第一个text文本节点
     * **/
    getEleFirstTextNode: function (ele) {
        
        if (ele.nodeType === 3) {
            return ele;
        }else{
            if (ele.tagName === "IMG") {
                ele = this._getSpan().insertBefore($(ele).parent());
            }
        }
        var childNodes;
        if (ele.css) {
            childNodes = ele[0].childNodes;
        } else {
            childNodes = ele.childNodes;
        }
        var firstEle  = childNodes[0];
        if (firstEle.nodeType === 3) {
            return firstEle;
        }
        if (firstEle.tagName === "IMG") {
            firstEle = this._getSpan().insertBefore($(firstEle).parent());
        }
        return this.getEleFirstTextNode(firstEle);
    },
    /**
     * 获取ele元素下最后一个text文本节点
     * **/
    getEleLastTextNode: function (ele) {
        if (ele.nodeType === 3) {
            return ele;
        }else{
            if (ele.tagName === "IMG") {
                ele = this._getSpan().insertAfter($(ele).parent());
            }
        }
        var childNodes;
        if (ele.css) {
            childNodes = ele[0].childNodes;
        } else {
            childNodes = ele.childNodes;
        }
        var lastEle = childNodes[childNodes.length - 1];
        if (!lastEle) {
            console.log("异常！！！！");
            return;
        }
        if (lastEle.nodeType === 3) {
            return lastEle;
        }
        if (lastEle.tagName === "IMG") {
            lastEle = this._getSpan().insertAfter($(lastEle).parent());
        }
        return this.getEleLastTextNode(lastEle);
    },
    /**创建新的选区
     * 确保新的range里开始节点、结束节点为text-node类型
     * start ：此处为jq对象 / 文本节点;
     * end ：此处为jq对象 / 文本节点
     * **/
    createCrossRange: function (start, end) {
        var firstTextNode = this.getEleFirstTextNode(start);
        var lastTextNode = this.getEleLastTextNode(end);
        return this.setCrossRange(firstTextNode, lastTextNode, 0, lastTextNode.length);
    },
    /***
     * firstChild：开始节点，必须为文本节点;
     * lastChild：结束节点，必须为文本节点;
     * startOffset：开始位置;
     * endOffset：结束位置
     * ***/
    setCrossRange: function (firstChild, lastChild, startOffset, endOffset) {
        try {
            var range = document.createRange();
            range.setStart(firstChild, startOffset);
            range.setEnd(lastChild, endOffset);
            var sel = window.getSelection();
            try {
                sel.removeAllRanges();
            } catch (ex) { }
            sel.addRange(range);
            this.range = range;
            this.setStartAndEndPElementByRange();
            return this.range;
        } catch (ex) {
            console.log("error");
        }
    },
    /**
     * section是否是空段落
     * **/
    isEmptySectionFn: function (section) {
        var txt = section.text().replace(/[\s*\u200B]*/g, "");
        var isEmpty = txt === "";
        if (isEmpty) {
            var tables = section.find("table").length;
            var imgs = section.find("img").length;
            isEmpty = tables === 0 && imgs === 0;
        }
        return isEmpty;
    },
    /**
     *获取选区开始节点/结束节点所在的段落jq对象 
     *isStart : 获取开始节点所在段落，否则获取结束节点所在段落
     * **/
    getRangeSection: function (isStart) {
        var section;
        if (this.range) {
            var container = this.range.endContainer;
            if (isStart) {
                container = this.range.startContainer;
            }
            if (container.nodeType === 3) {
                container = container.parentNode;
            }
            while (container) {
                if (container.nodeName === "DIV") {
                    section = container;
                    break;
                }
                container = container.parentNode;
            }
            if (section) {
                var tmp = $(section);
                if (tmp.hasClass("_section_div_")) {
                    section = tmp;
                } else {
                    section = undefined;
                }
            }
        }
        return section;
    },
    destroy: function () {
        var i,len;
        for(i = 0 ,len = this.tables.length ; i < len ; ++i){
            if(this.tables[i].remove){
                this.tables[i].remove();
            }
        }
        this.FLOW_CACHE = undefined;
        clearInterval(this._cache_clearner);
        $(document).off("mousedown."+this.id);
        if (this["resizeBox"]) {
            this["resizeBox"].destroy();
        }
        if (this["floatTools"]) {
            this["floatTools"].destroy();
        }
        if (this["floatPropPanel"]) {
            this["floatPropPanel"].destroy();
        }
        if (this.undoStack) {
            this.undoStack.destroy();
        }
        if (this.redoStack) {
            this.redoStack.destroy();
        }
        if (this.tools) {
            this.tools.destroy();
        }
        if (this["mousemenu"]) {
            this["mousemenu"].remove();
        }
        if (this["tipWindow"]) {
            this["tipWindow"].remove();
        }
        if (window["TableProps"] && window["TableProps"].destroy) {
            window["TableProps"].destroy();
        }
        if (this.windowArray) {
            for (i = 0, len = this.windowArray.length; i < len; ++i) {
                var w = this.windowArray[i];
                if (w.data("colorPicker")) {
                    w.data("colorPicker").destroy();
                }
                if (w.remove) {
                    w.remove();
                }
            }
        }
        if (this.super) {
            this.super.destroy.call(this);
        }
        //处理视频videojs，避免html加载方式下，videojs内部记录的数据不销毁
        if (window["videojs"]) {
            var players = window["videojs"].getPlayers();
            if (players) {
                for (var p in players) {
                    if (players.hasOwnProperty(p)) {
                        delete players[p];
                    }
                }
            }
        }
    }
};

Kedit.prototype.flow = function () {
    this.flowOpen();
};
Kedit.prototype.flowOpen = function (dataJson, flowImg) {
    var width = this.$fixInput.width();
    var height = _getBody().height() - this.$fixInput.offset().top;
    var jqHref = $("script#flowjqplus").attr("src").replace("flowjqplus.js", "");
    var date = new Date();
    var diff = date.getMinutes() + "" + date.getSeconds() + date.getMilliseconds() + parseInt(Math.random() * 100);
    var src0 = jqHref.replace("flow/", "") + "jquery.min.js";
    var src1 = jqHref + "snap.svg-min.js";
    var src2 = jqHref + "config.js?t=" + diff;
    var src3 = jqHref + "flow-all-0.0.1.js?t=" + diff;
    var struct = '<div id="f_loading" style="padding:0;marign:0;padding-left:20px;"><i style="padding: 0;margin: 0;font-size: 14px;line-height: 1.5em;font-family: "Microsoft Yahei", Helvetica, Arial, sans-serif;color: #666666;" class="fa animate-spin fa-spin6"></i>loading........</div><div id="f_main" style="width:100%;height:100%;position: relative;display:none;"><div class="k_box_size" id="left_container"></div><div class="k_box_size" id="right_container"><div class="k_box_size" id="canvas_container" style="overflow:auto;"><svg tabindex="0" id="myflow" class="k_box_size" style="width:100%;height:100%;vertical-align:top;"></svg></div></div><div style="border-top:1px solid #40ADFF;border-right:1px solid #40ADFF;" class="k_box_size" id="top_container"><div id="f_title" style="float:left;font-size:16px;line-height:34px;height:100%;padding:0 18.5px;background: #40ADFF;color:#fff;">Bui-flow</div><div id="f_tools" style="margin-left:30px;float:left;line-height:34px;height:100%;padding:0 28px;"></div><div id="f_tools_r" style="float:right;line-height:34px;height:100%;padding:0 28px;"></div></div></div>';
    var onloadScript = '<script> var ivt = setInterval(function () { ' + "\n\r" + 'if (window.$ && window.$B && window.$B.Flow && window.$B.flowConfig && window.Snap)' + "\n\r" + ' {' + "\n\r" + ' clearInterval(ivt); $("body").css("position","relative");var $l = $("#f_loading").hide();$l.next().show(); parent._KBCreateFlow($B, $("#myflow")[0]); }' + "\n\r" + 'else{' + "\n\r" + 'console.log("等待资源加载完成.....");}},200);<\/script>';
    this.flowScriptSrcs = {
        src: [src0, src1, src2, src3],
        struct: struct,
        onloadScript: onloadScript,
        flowcss: jqHref + "flow.css"
    };
    var _this = this;
    window._KBCreateFlow = function ($_B, $el) {
        _this.flowIns = new $_B.Flow($el, {
            uploadIconUrl: _this.opts.uploadFlowIconUrl,
            onSave: function (json) {
                _this.flowIns.getImgBase64(function (base64, width, height) {
                    var fjson = _this.flowIns.toJson();
                    _this.flowIns.destroy();
                    _this.insertFlow(base64, width, height, fjson);
                    _this.closeWindow();
                });
            }
        });
        if (dataJson) {
            _this.flowIns.drawByJson(dataJson);
        }
    };
    var bHeight = _getBody().height();
    if (height > bHeight) {
        height = bHeight;
    }
    this.openWindow({
        title: eConfig.label.drawFlow,
        width: width,
        height: height,
        contentFn: function (body, prs) {
        }
    }, {}, undefined, "flowDesignWindow");
    this.flowScriptSrcs = undefined;
    this.flowDesignWindow.data("rmDom", true);//窗口关闭即删除dom
    this.flowUpdateImg = flowImg;
};
/**插入流程图***/
Kedit.prototype.insertFlow = function (imgData, width, height, flowJson) {
    var id, _this = this;
    if (flowJson.id) {//执行更新
        id = flowJson.id;
        this.flowUpdateImg[0].src = imgData;
        this.flowUpdateImg.css({ width: width, height: height });
        if (typeof this.opts.onInsertFlowAfter === "function") {
            var updateImg = _this.flowUpdateImg;
            setTimeout(function () {
                _this.opts.onInsertFlowAfter(updateImg, flowJson, true);
            }, 50);
        }
    } else {
        var src = imgData;
        if (typeof this.opts.onInsertFlow === "function") {
            var tmp = this.opts.onInsertFlow(imgData);
            if (tmp) {
                src = tmp;
            }
        }
        var prs = {
            "undo": false,
            "needRange": false,
            "url": src,
            "width": width,
            "height": height,
            "position": "left"
        };
        var img = this.picture(prs);
        id = img.addClass("k_editor_flow_img").attr("id");
        if (typeof this.opts.onInsertFlowAfter === "function") {
            setTimeout(function () {
                _this.opts.onInsertFlowAfter(img, flowJson, false);
            }, 50);
        }
    }
    flowJson.id = id;
    this.FLOW_CACHE[id] = flowJson;
};
/**
 * 设置流程数据 内部调用setFlowCacheById
 * datas:流程数据数组
 * ***/
Kedit.prototype.setFlowDatas = function (datas) {
    for (var i = 0, len = datas.length; i < len; ++i) {
        this.setFlowCacheById(datas[i].id, datas[i]);
    }
};
/**id:流程id ，flowjson：流程json***/
Kedit.prototype.setFlowCacheById = function (id, flowJson) {
    this.FLOW_CACHE[id] = flowJson;
};
/**
* 打开边框设置窗口
* ***/
Kedit.prototype.openBorderForm = function (jqObj) {
    //console.log("打开 openBorderForm");
    var _this = this;
    _this.currentBorderObj = jqObj.addClass("k_editor_closed_section");
    this.onWindowClosed = function () {
        _this.currentBorderObj.removeClass("k_editor_closed_section");
        _this.currentBorderObj = undefined;
    };
    this.openWindow({
        title: eConfig.label.setborder,
        width: 350,
        height: 200,
        contentFn: function (body, prs) {
            if (!_this["borderForm"]) {
                _this["borderForm"] = $("<div style='width:100%;height:100%;position:relative;padding-left:40px;' class='k_box_size'></div>");
                _this["borderForm"].append(eConfig.borderForm);
                _this._createWindowColorPicker();
                var f = _this["borderForm"];
                var $_border_pos = f.find("#k_border_pos");
                var $_border_style = f.find("#k_border_style");
                var $_border_size = f.find("#k_border_size");
                var $_icon_color = f.find("#k_icon_color");
                var getBodyprexFn = function () {
                    var borderPosArray = [];
                    $_border_pos.children("._act").each(function () {
                        borderPosArray.push("border-" + $(this).attr("v") + "-");
                    });
                    return borderPosArray;
                };
                var posClickFn = function () {
                    var $o = $(this);
                    if ($o.hasClass("_act")) {
                        $o.css("background-color", 'transparent').removeClass("_act");
                    } else {
                        $o.css("background-color", '#2EF5FF').addClass("_act");
                    }
                    var exePrs, bsize, bcolor, bstyle;
                    var borders = getBodyprexFn();
                    if (borders.length === 0) {
                        exePrs = { "border": "none" };
                    } else {
                        bsize = $_border_size.val();
                        bcolor = $_icon_color.css("background-color");
                        bstyle = $_border_style.val();
                        var bcss = {};
                        for (var i = 0, len = borders.length; i < len; ++i) {
                            bcss[borders[i] + "style"] = bstyle;
                            bcss[borders[i] + "width"] = bsize;
                            bcss[borders[i] + "color"] = bcolor;
                        }
                        exePrs = bcss;
                    }
                    //执行边框修饰.....
                    //console.log("执行修饰>>>>>>>>" +  JSON.stringify(exePrs) );
                    _this.currentBorderObj.css("border", "none").css(exePrs);
                };

                //选择事件 ,行高，边框位置，边框类型
                var onSelectedFn = function () {
                    var $this = $(this);
                    var val = $this.val();
                    var exePrs = $.extend({}, prs);
                    var bstyle, bsize, bcolor, bcss, i, len, borders;
                    var elId = $this.attr("id");
                    if (elId === "k_border_style") {//边框类型
                        borders = getBodyprexFn();
                        if (borders.length === 0) {
                            exePrs = { "border": "none" };
                        } else {
                            bsize = $_border_size.val();
                            bcolor = $_icon_color.css("background-color");
                            bcss = {};
                            for (i = 0, len = borders.length; i < len; ++i) {
                                bcss[borders[i] + "style"] = val;
                                bcss[borders[i] + "width"] = bsize;
                                bcss[borders[i] + "color"] = bcolor;
                            }
                            exePrs = bcss;
                        }
                        //console.log("执行修饰>>>>>>>>" +  JSON.stringify(exePrs) );
                    } else if (elId === "k_border_size") {//边框大小
                        borders = getBodyprexFn();
                        if (borders.length === 0) {
                            exePrs = { "border": "none" };
                        } else {
                            bcolor = $_icon_color.css("background-color");
                            bstyle = $_border_style.val();
                            bcss = {};
                            for (i = 0, len = borders.length; i < len; ++i) {
                                bcss[borders[i] + "style"] = bstyle;
                                bcss[borders[i] + "width"] = val;
                                bcss[borders[i] + "color"] = bcolor;
                            }
                            exePrs = bcss;
                        }
                        //console.log("执行修饰>>>>>>>>" +  JSON.stringify(exePrs) );                       
                    }
                    _this.currentBorderObj.css("border", "none").css(exePrs);
                };

                $_border_style.on("change", onSelectedFn);
                $_border_size.on("change", onSelectedFn);
                //边框位置 
                $("<span class='_border_pos' v='left'  style='border:1px dashed #CCCCCC;border-left:2px solid #0000FF;cursor:pointer; display:inline-block;width:15px;height:15px;margin-right:8px;'></span>").appendTo($_border_pos).click(posClickFn);
                $("<span class='_border_pos' v='top'  style='border:1px dashed #CCCCCC;border-top:2px solid #0000FF;cursor:pointer; display:inline-block;width:15px;height:15px;margin-right:8px;'></span>").appendTo($_border_pos).click(posClickFn);
                $("<span class='_border_pos' v='right' style='border:1px dashed #CCCCCC;border-right:2px solid #0000FF;cursor:pointer; display:inline-block;width:15px;height:15px;margin-right:8px;'></span>").appendTo($_border_pos).click(posClickFn);
                $("<span class='_border_pos' v='bottom' style='border:1px dashed #CCCCCC;border-bottom:2px solid #0000FF;cursor:pointer; display:inline-block;width:15px;height:15px;margin-right:8px;'></span>").appendTo($_border_pos).click(posClickFn);

                var ifrPos = _this[_this.windowName + "_iframe"].offset();
                var picker = _this[_this.windowName].data("colorPicker");
                picker.opts.positionFix = {
                    left: ifrPos.left + 4,
                    top: ifrPos.top + 4
                };
                //边框颜色
                $_icon_color.mousedown(function () {
                    picker.hideImd(true);
                    picker.setTarget($(this));
                    var borders = getBodyprexFn();
                    var bstyle = $_border_style.val();
                    var bsize = $_border_size.val();
                    picker.opts.change = function (hex, opacity) {
                        if (borders.length > 0) {
                            var bcss = {};
                            for (var i = 0, len = borders.length; i < len; ++i) {
                                bcss[borders[i] + "style"] = bstyle;
                                bcss[borders[i] + "width"] = bsize;
                                bcss[borders[i] + "color"] = hex;
                            }
                            //var exePrs = { "border": bcss };
                            console.log("执行修饰>>>>>>>>" + JSON.stringify(bcss));
                            _this.currentBorderObj.css("border", "none").css(bcss);
                        }
                    };
                    picker.setValue($(this).css("background-color"), false);
                });

                f.find("button").click(function () {
                    _this.closeWindow();
                });

                _this["borderForm"].data("form", {
                    borderPos: $_border_pos,
                    borderStyle: $_border_style,
                    borderColor: $_icon_color,
                    borderSize: $_border_size
                });
            }
            //联动
            var borderCss;
            var border = _this._getJqObjBorders(_this.currentBorderObj);
            var form = _this["borderForm"].data("form");
            var colorPicker = _this[_this.windowName].data("colorPicker");
            form.borderPos.children().each(function () {
                var $o = $(this);
                if (border[$o.attr("v")]) {
                    $o.css("background-color", '#2EF5FF').addClass("_act");
                    borderCss = border[$o.attr("v")];
                } else {
                    $o.css("background-color", 'transparent').removeClass("_act");
                }
            });
            var fn1 = function (i, opt, prpName) {
                if (borderCss) {
                    if (borderCss[prpName] === opt.attr("value")) {
                        opt.prop("selected", true);
                    } else {
                        opt.prop("selected", false);
                    }
                } else {
                    if (i === 0) {
                        opt.prop("selected", true);
                    } else {
                        opt.prop("selected", false);
                    }
                }
            };
            form.borderStyle.children().each(function (i) {
                var opt = $(this);
                fn1(i, opt, "style");
            });
            form.borderSize.children().each(function (i) {
                var opt = $(this);
                fn1(i, opt, "width");
            });
            var trastColor;
            if (borderCss) {
                trastColor = colorPicker.getContrastColor(borderCss.color);
                form.borderColor.css({ "background-color": borderCss.color, "color": trastColor });
            } else {
                form.borderColor.css({ "background-color": "#666666", "color": "#ffffff" });
            }
            body.append(_this["borderForm"]);
        }
    }, {}, this.setWindowColorPickerPosition);
    this.setWindowColorPickerPosition();
},
/**
 * 设置colorpicker位置
 * ****/
Kedit.prototype.setWindowColorPickerPosition = function () {
    var _this = this;
    var winIfr = _this[_this.windowName + "_iframe"];
    if (winIfr) {
        var ifrPos = winIfr.offset();
        var win = _this[_this.windowName];
        if (win) {
            var picker = win.data("colorPicker");
            if (picker) {
                picker.opts.positionFix = {
                    left: ifrPos.left + 4,
                    top: ifrPos.top + 2
                };
            }
        }
    }
};
/***
 * 打开段落窗口
 * ***/
Kedit.prototype.openParagrapWindow = function (method, params, $btn) {
    var _this = this;
    if (!this.startPElement) {
        $B.alert(eConfig.label.selectedSectionTip, 3);
        return;
    }
    this.openWindow({
        title: eConfig.label.paragraph,
        width: 450,
        height: 300,
        contentFn: function (body, prs) {
            if (!_this["paragrapForm"]) {
                _this["paragrapForm"] = $("<div style='width:100%;height:100%;position:relative;' class='k_box_size'></div>");
                _this["paragrapForm"].append(eConfig.paragraphForm);
                _this._createWindowColorPicker();
                var f = _this["paragrapForm"];
                var userInputFn = function () {
                    var $t = $(this);
                    var id = $t.attr("id").replace(/_/g, "");
                    var v = $t.val();
                    if (/\d+/.test(v)) {
                        $t.removeClass("k_input_value_err");
                        var exePrs = $.extend({}, prs);
                        exePrs[id] = v;
                        _this.paragraph(exePrs);
                    } else {
                        $t.addClass("k_input_value_err");
                    }
                };
                var $_indent_ = f.find("#_indent_").on("input", userInputFn);
                var $_margin_top_ = f.find("#_margin-top_").on("input", userInputFn);
                var $_margin_bottom_ = f.find("#_margin-bottom_").on("input", userInputFn);
                var $_padding_left_ = f.find("#_padding-left_").on("input", userInputFn);
                var $_padding_right_ = f.find("#_padding-right_").on("input", userInputFn);
                var $_line_height_ = f.find("#_line-height_");
                var $_border_pos = f.find("#_border_pos");
                var $_border_style = f.find("#_border_style");
                var $_border_size = f.find("#_border_size");
                var $_icon_color = f.find("#_icon_color");

                var getBodyprexFn = function () {
                    var borderPosArray = [];
                    $_border_pos.children("._act").each(function () {
                        borderPosArray.push("border-" + $(this).attr("v") + "-");
                    });
                    return borderPosArray;
                };

                var posClickFn = function () {
                    var $o = $(this);
                    if ($o.hasClass("_act")) {
                        $o.css("background-color", 'transparent').removeClass("_act");
                    } else {
                        $o.css("background-color", '#2EF5FF').addClass("_act");
                    }
                    var exePrs, bsize, bcolor, bstyle;
                    var borders = getBodyprexFn();
                    if (borders.length === 0) {
                        exePrs = { "border": "none" };
                    } else {
                        bsize = $_border_size.val();
                        bcolor = $_icon_color.css("background-color");
                        bstyle = $_border_style.val();
                        var bcss = {};
                        for (var i = 0, len = borders.length; i < len; ++i) {
                            bcss[borders[i] + "style"] = bstyle;
                            bcss[borders[i] + "width"] = bsize;
                            bcss[borders[i] + "color"] = bcolor;
                        }
                        exePrs = { "border": bcss };
                    }
                    _this.paragraph(exePrs);
                };

                //选择事件 ,行高，边框位置，边框类型
                var onSelectedFn = function () {
                    var $this = $(this);
                    var val = $this.val();
                    var exePrs = $.extend({}, prs);
                    var bstyle, bsize, bcolor, bcss, i, len, borders;
                    //console.log("onSelectedFn " + val);
                    var elId = $this.attr("id");
                    if (elId === "_line-height_") {
                        exePrs["line-height"] = val;
                        _this.paragraph(exePrs);
                    } else if (elId === "_border_style") {//边框类型
                        borders = getBodyprexFn();
                        if (borders.length === 0) {
                            exePrs = { "border": "none" };
                        } else {
                            bsize = $_border_size.val();
                            bcolor = $_icon_color.css("background-color");
                            bcss = {};
                            for (i = 0, len = borders.length; i < len; ++i) {
                                bcss[borders[i] + "style"] = val;
                                bcss[borders[i] + "width"] = bsize;
                                bcss[borders[i] + "color"] = bcolor;
                            }
                            exePrs = { "border": bcss };
                        }
                        _this.paragraph(exePrs);
                    } else if (elId === "_border_size") {//边框大小
                        borders = getBodyprexFn();
                        if (borders.length === 0) {
                            exePrs = { "border": "none" };
                        } else {
                            bcolor = $_icon_color.css("background-color");
                            bstyle = $_border_style.val();
                            bcss = {};
                            for (i = 0, len = borders.length; i < len; ++i) {
                                bcss[borders[i] + "style"] = bstyle;
                                bcss[borders[i] + "width"] = val;
                                bcss[borders[i] + "color"] = bcolor;
                            }
                            exePrs = { "border": bcss };
                        }
                        _this.paragraph(exePrs);
                    }
                };
                $_line_height_.on("change", onSelectedFn);
                $_border_style.on("change", onSelectedFn);
                $_border_size.on("change", onSelectedFn);

                //边框位置 
                $("<span class='_border_pos' v='left'  style='border:1px dashed #CCCCCC;border-left:2px solid #0000FF;cursor:pointer; display:inline-block;width:15px;height:15px;margin-right:8px;'></span>").appendTo($_border_pos).click(posClickFn);
                $("<span class='_border_pos' v='top'  style='border:1px dashed #CCCCCC;border-top:2px solid #0000FF;cursor:pointer; display:inline-block;width:15px;height:15px;margin-right:8px;'></span>").appendTo($_border_pos).click(posClickFn);
                $("<span class='_border_pos' v='right' style='border:1px dashed #CCCCCC;border-right:2px solid #0000FF;cursor:pointer; display:inline-block;width:15px;height:15px;margin-right:8px;'></span>").appendTo($_border_pos).click(posClickFn);
                $("<span class='_border_pos' v='bottom' style='border:1px dashed #CCCCCC;border-bottom:2px solid #0000FF;cursor:pointer; display:inline-block;width:15px;height:15px;margin-right:8px;'></span>").appendTo($_border_pos).click(posClickFn);

                var ifrPos = _this[_this.windowName + "_iframe"].offset();
                var picker = _this[_this.windowName].data("colorPicker");
                picker.opts.positionFix = {
                    left: ifrPos.left + 4,
                    top: ifrPos.top + 4
                };
                //边框颜色
                $_icon_color.mousedown(function () {
                    picker.hideImd(true);
                    picker.setTarget($(this));
                    var borders = getBodyprexFn();
                    var bstyle = $_border_style.val();
                    var bsize = $_border_size.val();
                    picker.opts.change = function (hex, opacity) {
                        if (borders.length > 0) {
                            var bcss = {};
                            for (var i = 0, len = borders.length; i < len; ++i) {
                                bcss[borders[i] + "style"] = bstyle;
                                bcss[borders[i] + "width"] = bsize;
                                bcss[borders[i] + "color"] = hex;
                            }
                            var exePrs = { "border": bcss };
                            _this.paragraph(exePrs);
                        }
                    };
                    picker.setValue($(this).css("background-color"), false);
                });

                //背景色  _bg_color
                var $_bg_color = f.find("#_bg_color");
                $_bg_color.mousedown(function () {
                    picker.hideImd(true);
                    picker.setTarget($(this));

                    picker.opts.change = function (hex, opacity) {//注册颜色变化函数 
                        var exePrs = $.extend({}, prs);
                        exePrs["background-color"] = hex;
                        _this.paragraph(exePrs);
                    };
                    var bg = $(this).css("background-color");
                    picker.setValue(bg, false);
                    console.log("激活背景色");
                });

                //字体颜色
                var $_font_color = f.find("#_font_color");
                $_font_color.mousedown(function () {
                    picker.hideImd(true);
                    picker.setTarget($(this));
                    picker.opts.change = function (hex, opacity) {//注册颜色变化函数 
                        var exePrs = $.extend({}, prs);
                        exePrs["color"] = hex;
                        _this.paragraph(exePrs);
                    };
                    picker.setValue($(this).css("background-color"), false);
                });

                //是否阴影
                var $_shadow = f.find("#_shadow").on("click", function () {
                    var $box = $(this);
                    var exePrs = $.extend({}, prs);
                    if ($box.prop("checked")) {
                        exePrs["box-shadow"] = "0 3px 5px -1px rgba(0, 0, 0, .2), 0 6px 10px 0 rgba(0, 0, 0, .14), 0 1px 18px 0 rgba(0, 0, 0, .12)";
                    } else {
                        exePrs["box-shadow"] = "none";
                    }
                    _this.paragraph(exePrs);
                });

                f.find("button").click(function () {
                    _this.closeWindow();
                    _this.removeSectionResizeBar();
                });
                _this["paragrapForm"].data("form", {
                    indent: $_indent_,
                    top: $_margin_top_,
                    bottom: $_margin_bottom_,
                    left: $_padding_left_,
                    right: $_padding_right_,
                    lineHeight: $_line_height_,
                    borderPos: $_border_pos,
                    borderStyle: $_border_style,
                    borderColor: $_icon_color,
                    borderSize: $_border_size,
                    backgroundColor: $_bg_color,
                    fontColor: $_font_color,
                    shadow: $_shadow
                });
            }
            var colorPicker = _this[_this.windowName].data("colorPicker");
            var style = _this.getParagraphcss();
            var form = _this["paragrapForm"].data("form");

            //边框
            var border = style.border;
            var borderCss;
            form.borderPos.children().each(function () {
                var $o = $(this);
                if (border[$o.attr("v")]) {
                    $o.css("background-color", '#2EF5FF').addClass("_act");
                    borderCss = border[$o.attr("v")];
                } else {
                    $o.css("background-color", 'transparent').removeClass("_act");
                }
            });
            var fn1 = function (i, opt, prpName) {
                if (borderCss) {
                    if (borderCss[prpName] === opt.attr("value")) {
                        opt.prop("selected", true);
                    } else {
                        opt.prop("selected", false);
                    }
                } else {
                    if (i === 0) {
                        opt.prop("selected", true);
                    } else {
                        opt.prop("selected", false);
                    }
                }
            };
            form.borderStyle.children().each(function (i) {
                var opt = $(this);
                fn1(i, opt, "style");
            });
            form.borderSize.children().each(function (i) {
                var opt = $(this);
                fn1(i, opt, "width");
            });
            var trastColor;
            if (borderCss) {
                trastColor = colorPicker.getContrastColor(borderCss.color);
                form.borderColor.css({ "background-color": borderCss.color, "color": trastColor });
            } else {
                form.borderColor.css({ "background-color": "#666666", "color": "#ffffff" });
            }
            //边框结束
            //背景色
            var bgColor = style["background-color"];
            trastColor = colorPicker.getContrastColor(bgColor);
            form.backgroundColor.css({ "background-color": bgColor, "color": trastColor });
            //字体颜色
            var fontColor = style["color"];
            trastColor = colorPicker.getContrastColor(fontColor);
            form.fontColor.css({ "background-color": fontColor, "color": trastColor });

            form.indent.val(style.indent);
            form.top.val(style["margin-top"]);
            form.bottom.val(style["margin-bottom"]);

            form.left.val(style["padding-left"]);
            form.right.val(style["padding-right"]);
            style["line-height"] = style["line-height"] + "";
            form.lineHeight.children().each(function () {
                var opt = $(this);
                if (opt.attr("value") === style["line-height"]) {
                    opt.prop("selected", true);
                } else {
                    opt.prop("selected", false);
                }
            });

            body.append(_this["paragrapForm"]);
            _this.setSectionWidth(true);
        }
    }, params, this.setWindowColorPickerPosition);
    this.setWindowColorPickerPosition();
};
/**
 * 获取jq元素对象的边框
 * ***/
Kedit.prototype._getJqObjBorders = function (pele) {
    var borders = {};
    var bcolor = pele.css("border-top-color");
    var bwidth = pele.css("border-top-width");
    var bstyle = pele.css("border-top-style");
    if (bstyle !== "none") {
        borders["top"] = { color: bcolor, width: bwidth, style: bstyle };
    }

    bcolor = pele.css("border-right-color");
    bwidth = pele.css("border-right-width");
    bstyle = pele.css("border-right-style");
    if (bstyle !== "none") {
        borders["right"] = { color: bcolor, width: bwidth, style: bstyle };
    }

    bcolor = pele.css("border-bottom-color");
    bwidth = pele.css("border-bottom-width");
    bstyle = pele.css("border-bottom-style");
    if (bstyle !== "none") {
        borders["bottom"] = { color: bcolor, width: bwidth, style: bstyle };
    }

    bcolor = pele.css("border-left-color");
    bwidth = pele.css("border-left-width");
    bstyle = pele.css("border-left-style");
    if (bstyle !== "none") {
        borders["left"] = { color: bcolor, width: bwidth, style: bstyle };
    }
    return borders;
};
/**
 * 获取选区所在的段落样式
 * ****/
Kedit.prototype.getParagraphcss = function () {
    //console.log("getParagraphcss >>>");
    var css = {
        indent: undefined,
        "margin-top": undefined,
        "margin-bottom": undefined,
        "padding-left": undefined,
        "padding-right": undefined,
        "line-height": undefined,
        "background-color": undefined,
        "border": undefined,
        "color": undefined
    };
    var _this = this;
    this.foreachPTargets(function (pele, i) {
        if (!pele.hasClass("_exclude_")) {
            var borders = _this._getJqObjBorders(pele);
            css["border"] = borders;
            var children = pele.children();
            children.each(function () {
                if (this.tagName === "PRE") {
                    return true;
                }
                var $c = $(this);
                var color;
                if ($c[0].tagName === "TABLE") {
                    $c.find("td").each(function () {
                        var td = $(this);
                        color = td.css("color");
                        if (!css["color"]) {
                            css["color"] = color;
                        } else if (css["color"] !== color) {
                            css["color"] = "#666666";
                        }
                    });
                } else {
                    if ($c.children().length === 0) {
                        color = $c.css("color");
                        if (!css["color"]) {
                            css["color"] = color;
                        } else if (css["color"] !== color) {
                            css["color"] = "#666666";
                        }
                    }
                }
            });
            var backgroundColor = pele.css("background-color");
            if (!css["background-color"]) {
                css["background-color"] = backgroundColor;
            } else if (css["background-color"] !== backgroundColor) {
                css["background-color"] = undefined;
            }

            var text_indent = pele.css("text-indent");
            if (text_indent) {
                var firstFontSize = _this.getFirstCharFontSize(pele);
                text_indent = parseFloat(text_indent.replace("px", "")) / firstFontSize;
                if (!css["indent"]) {
                    css["indent"] = text_indent;
                } else if (css["indent"] !== text_indent) {
                    css["indent"] = "";
                }
            }
            var maxFs = _this._getParagraphMaxFontSize(pele);
            var line_height = (parseFloat(pele.css("line-height"), "") / maxFs).toFixed(1);
            //console.log("line_height === "+line_height);
            if (!css["line-height"]) {
                css["line-height"] = line_height;
            } else if (css["line-height"] !== line_height) {
                css["line-height"] = undefined;
            }
            var margin_top = parseInt(pele.css("margin-top"), "");
            if (!css["margin-top"]) {
                css["margin-top"] = margin_top;
            } else if (css["margin-top"] !== margin_top) {
                css["margin-top"] = "";
            }
            var margin_bottom = parseInt(pele.css("margin-bottom"), "");
            if (!css["margin-bottom"]) {
                css["margin-bottom"] = margin_bottom;
            } else if (css["margin-bottom"] !== margin_bottom) {
                css["margin-bottom"] = "";
            }
            var padding_left = parseInt(pele.css("padding-left"), "");
            if (!css["padding-left"]) {
                css["padding-left"] = padding_left;
            } else if (css["padding-left"] !== padding_left) {
                css["padding-left"] = "";
            }
            var padding_right = parseInt(pele.css("padding-right"), "");
            if (!css["padding-right"]) {
                css["padding-right"] = padding_right;
            } else if (css["padding-right"] !== padding_right) {
                css["padding-right"] = "";
            }
        }
    });
    //console.log(JSON.stringify(css));
    if (!css["color"]) {
        css["color"] = "#666666";
    }
    return css;
};
/**段落修饰**/
Kedit.prototype.paragraph = function (params) {
    var clear = false;
    var css = {};
    var firstCharSize = 14;
    var indent;
    if (typeof params["indent"] !== "undefined" && params["indent"] !== "") {
        indent = params["indent"];
    }
    if (typeof params["margin-top"] !== "undefined" && params["margin-top"] !== "") {
        css["margin-top"] = params["margin-top"] + "px";
    }
    if (typeof params["margin-bottom"] !== "undefined" && params["margin-bottom"] !== "") {
        css["margin-bottom"] = params["margin-bottom"] + "px";
    }

    if (typeof params["padding-left"] !== "undefined" && params["padding-left"] !== "") {
        css["padding-left"] = params["padding-left"] + "px";
    }
    if (typeof params["padding-right"] !== "undefined" && params["padding-right"] !== "") {
        css["padding-right"] = params["padding-right"] + "px";
    }
    var line_height;
    if (typeof params["line-height"] !== "undefined" && params["line-height"] !== "") {
        line_height = parseFloat(params["line-height"]);
    }
    if (typeof params["background-color"] !== "undefined" && params["background-color"] !== "") {
        css["background-color"] = params["background-color"];
    }
    if (typeof params["box-shadow"] !== "undefined" && params["box-shadow"] !== "") {
        css["box-shadow"] = params["box-shadow"];
    }

    var isBorder = false;
    //边框修饰
    if (typeof params["border"] !== "undefined") {
        isBorder = true;
        if ($.isPlainObject(params["border"])) {
            css = params["border"];
        } else {
            css = params;
        }
    }
    //console.log("paragraph >>>>> " + JSON.stringify(css));
    if (typeof params["color"] !== "undefined" && params["color"] !== "") {
        css["color"] = params["color"];
    }
    var _this = this;
    this.foreachPTargets(function (pele, i) {
        if (!pele.hasClass("_exclude_")) {
            if (typeof line_height !== "undefined") {
                var maxFs = _this._getParagraphMaxFontSize(pele);
                var lineHeight = line_height * maxFs;
                css["line-height"] = lineHeight + "px";
            }
            if (typeof indent !== "undefined") {
                firstCharSize = _this._getFirstCharFontSize(pele);
                var txtIndent = firstCharSize * indent;
                css["text-indent"] = txtIndent + "px";
            }
            if (!css["color"]) {
                if (isBorder) {
                    pele.css({ "border": "none" });
                }
                pele.css(css);
            }
            //对li 修饰行高
            if (css["line-height"]) {
                pele.find("li").css("line-height", css["line-height"]);
            } else if (css["background-color"] || css["color"]) {
                _this._css2pChildren(pele.children(), css);
            }
        }
    });
    if (clear) {
        this.startPElement = undefined;
        this.endPElement = undefined;
    }
};
/***
 * 段落修饰，修饰段落里的子元素
 * ***/
Kedit.prototype._css2pChildren = function (children, css) {
    var _this = this;
    children.each(function () {
        if (this.tagName === "PRE") {
            return true;
        }
        var $t = $(this);
        if (this.tagName === "SPAN" || this.tagName === "TD" || this.tagName === "P") {
            $t.css(css);
        }
        _this._css2pChildren($t.children(), css);
    });
};
/**
 * 插入浮动图片
 * ***/
Kedit.prototype.insertFloatImg = function () {
    var wrap = this._createFloatWindow(300, 230);
    var imgWrap = $("<div title='" + eConfig.label.dblUploadImg + "' class='k_box_size k_editor_float_img_wrap' style='width:100%;height:100%;position:absolute;z-index:20000001;background:none;top:0;left:0;'></div>");
    imgWrap.appendTo(wrap);
    $("<div style='width:100%;line-height:100px;text-align:center;font-weight:bold;font-size:1.2em;color:#A2A2A2;'>" + eConfig.label.dblUploadImg + "</div>").appendTo(imgWrap);
    this._bindFlowImgEvents(imgWrap);
};
Kedit.prototype._bindFlowImgEvents = function (imgWrap) {
    var _this = this;
    imgWrap.dblclick(function () {
        var $t = $(this);
        _this._floatImgWrap = $t;
        //创建隐藏的upload
        var body = _getBody();
        var uploadDiv = body.children("#editor_hidden_file_upload");
        if (uploadDiv.length === 0) {
            uploadDiv = $("<div id='editor_hidden_file_upload' style='position:absolute;z-index:-100;top:-100px;'></div>").appendTo(body);
            var uploadOpts = _this.opts.uploadImg;
            new $B.MutilUpload({
                target: uploadDiv,
                files: [{
                    name: '_k_edit_upolad_file',
                    type: '.png,.gif,.jpg,jpeg',
                    label: eConfig.label.selectImg,
                    must: true
                }],
                timeout: 190, //60秒钟超时             
                immediate: true, //选择文件后是否立即自动上传，即不用用户点击提交按钮就上传
                url: uploadOpts.url,
                success: function (res) { //成功时候的回调
                    //var target = _this._floatImgWrap;
                    var url = res.data;
                    if ($.isPlainObject(url)) {
                        url = res.data.url;
                    }
                    var zIndx = parseInt(_this._floatImgWrap.css("z-index"));
                    _this._floatImgWrap.html("<img src='" + url + "' style='width:100%;height:100%;position:relative;z-index:" + zIndx + "'/><div style='width:100%;height:100%;position:absolute;z-index:" + (zIndx + 1) + ";top:0;'></div>");
                    if (uploadOpts.onSuccess) {
                        uploadOpts.onSuccess.call(_this._floatImgWrap.children("img") ,res);
                    }
                },
                onselected: function () {
                    _this._floatImgWrap.html("<div style='width:100%;line-height:100px;text-align:center;font-weight:bold;font-size:1.2em;color:#A2A2A2;'><span style='color:#8E8E8E;font-size:1.2em;'><i style='color:#8E8E8E;font-size:1.2em;padding-right:6px;' class='fa fa-spinner fa-spin'></i>" + $B.config.uploading + "</span></div>");
                    return true;
                },
                error: function (res) { //错误回调
                    _this._floatImgWrap.html("<div style='width:100%;line-height:100px;text-align:center;font-weight:bold;font-size:1.2em;color:#A2A2A2;'><span style='color:#8E8E8E;font-size:1.2em;'><i style='color:#8E8E8E;font-size:1.2em;padding-right:6px;' class='fa fa-spinner'></i>" + eConfig.label.uploadError + "</span></div>");
                }
            });
        }
        uploadDiv.find(".k_visual_file_item_input").trigger("click");
    }).attr("title", eConfig.label.dblUploadImg);
};
Kedit.prototype.insertFloatText = function () {
    var wrap = this._createFloatWindow(300, 230);
    var id = getUUID();
    var input = $("<div spellcheck='false' id='" + id + "' class='k_box_size k_editor_float_input' contenteditable='true' style='padding:4px 5px;width:100%;height:100%;position:absolute;z-index:20000001;background:none;top:0;left:0;'></div>");
    input.appendTo(wrap);
    this.createPElement().appendTo(input).css("background", "none").children().each(function () {
        $(this).css("background", "none");
    });
    var _this = this;
    input.focus();
    _this.disabledFunc(eConfig.floatEidtor);
    _this._initInputEvents(input);
};
//打开图标窗口
Kedit.prototype.openIconWindow = function (method, params, $btn) {
    var _this = this;
    params["method"] = method;//
    this.openWindow({
        title: eConfig.label.insertIcon,
        width: 450,
        height: 300,
        contentFn: function (body, prs) {
            if (!_this["iconForm"]) {
                _this["iconForm"] = $("<div style='width:100%;height:100%;position:relative;' class='k_box_size'></div>");
                _this["iconForm"].append(eConfig.iconForm);
                _this["iconForm"].find("#_btn_").click(function () {
                    var canvas = _this["_icon_canvas"][0];
                    var dataURL = canvas.toDataURL("image/png");
                    console.log(dataURL);
                    _this.closeWindow();
                    prs.isIcon = true;
                    prs.icon = dataURL;
                    var w = _this["_icon_canvas"].width();
                    prs.width = w;
                    prs.height = w;
                    _this.emotion(prs);//走插入表情逻辑
                });
                var canvasWrap = $("<div style='position: absolute;right:0px;top:0px;width:50px;height:50px;'></div>").appendTo(_this["iconForm"]);
                _this["iconForm"].find("#_icons").children("span").click(function () {
                    var $s = $(this);
                    var font = $s[0].textContent;
                    var fontSize = parseInt(_this["iconForm"].find("#_tip_wrap").text().replace("px", ""));
                    var width = fontSize;
                    var height = width;
                    $s.css("color", "#FF8305").siblings().css("color", "#7E7E7E");
                    canvasWrap.children().remove();
                    var $canvas = $("<canvas id='myCanvas' width='" + width + "' height='" + height + "' style='border:1px solid #F7F7F7;'></canvas>").appendTo(canvasWrap);
                    var canvas = $canvas[0];
                    var context = canvas.getContext('2d');
                    context.fillStyle = '#7E7E7E';
                    context.font = fontSize + 'px fontello';
                    context.fillText(font, 0, height - 2, width);
                    $canvas.data("icon_data", {
                        "font-icon": font,
                        "color": '#7E7E7E',
                        "fontSize": fontSize
                    });
                    _this["_icon_canvas"] = $canvas;
                });
                var slider = _this["iconForm"].find("#_slider");
                var i1 = $("<i style='margin-right:10px;padding-top:4px;cursor:not-allowed;color:#D8D8D8;' class='fa  fa-fast-bw'></i>").appendTo(slider);
                var i2 = $("<i style='margin-right:10px;padding-top:4px;cursor:pointer;color:#7E7E7E;' class='fa  fa-fast-fw'></i>").appendTo(slider);
                i1.click(function () {
                    var $i = $(this);
                    var $txt = $i.parent().parent().next();
                    var srcV = parseInt($txt.text().replace("px", ""));
                    if (srcV === 12) {
                        return;
                    }
                    var v = srcV - 1;
                    if (v === 12) {
                        $i.css({
                            'cursor': 'not-allowed',
                            'color': '#D8D8D8'
                        });
                    }
                    if (v < 40) {
                        $i.next().css({
                            'cursor': 'pointer',
                            'color': '#7E7E7E'
                        });
                    }
                    $txt.text(v + "px");
                    var $canvas = _this["_icon_canvas"];
                    var canvas = $canvas[0];
                    var data = $canvas.data("icon_data");
                    var fontSize = v;
                    var context = canvas.getContext('2d');
                    canvas.height = fontSize;
                    canvas.width = fontSize;

                    context.fillStyle = data["color"];
                    context.font = fontSize + 'px fontello';

                    context.fillText(data["font-icon"], 0, canvas.height - 2, canvas.width);

                    $canvas.data("icon_data", {
                        "font-icon": data["font-icon"],
                        "color": data["color"],
                        "fontSize": fontSize
                    });

                });
                i2.click(function () {
                    var $i = $(this);
                    var $txt = $i.parent().parent().next();
                    var srcV = parseInt($txt.text().replace("px", ""));
                    if (srcV === 40) {
                        return;
                    }
                    var v = srcV + 1;
                    if (v === 40) {
                        $i.css({
                            'cursor': 'not-allowed',
                            'color': '#D8D8D8'
                        });
                    }
                    if (v > 12) {
                        $i.prev().css({
                            'cursor': 'pointer',
                            'color': '#7E7E7E'
                        });
                    }
                    $txt.text(v + "px");
                    var $canvas = _this["_icon_canvas"];
                    var canvas = $canvas[0];
                    var data = $canvas.data("icon_data");
                    var fontSize = v;
                    var context = canvas.getContext('2d');
                    canvas.height = fontSize;
                    canvas.width = fontSize;

                    context.fillStyle = data["color"];
                    context.font = fontSize + 'px fontello';

                    context.fillText(data["font-icon"], 0, canvas.height - 2, canvas.width);

                    $canvas.data("icon_data", {
                        "font-icon": data["font-icon"],
                        "color": data["color"],
                        "fontSize": fontSize
                    });
                });
                _this._createWindowColorPicker();
            }
            body.append(_this["iconForm"]);
            var $color = _this["iconForm"].find("#icon_color");
            var ifrPos = _this[_this.windowName + "_iframe"].offset();
            var picker = _this[_this.windowName].data("colorPicker");
            picker.unbindTarget();
            picker.opts.positionFix = {
                left: ifrPos.left + 4,
                top: ifrPos.top + 4
            };
            picker.setTarget($color).setValue('#7E7E7E');
            picker.opts.change = function (hex, opacity) {//注册颜色变化函数              
                if (_this["_icon_canvas"]) {
                    var canvas = _this["_icon_canvas"][0];
                    var data = _this["_icon_canvas"].data("icon_data");
                    var fontSize = data.fontSize;
                    var context = canvas.getContext('2d');
                    canvas.height = fontSize;
                    canvas.width = fontSize;
                    context.fillStyle = hex;
                    context.font = fontSize + 'px fontello';
                    context.fillText(data["font-icon"], 0, canvas.height - 2, canvas.width);
                    _this["_icon_canvas"].data("icon_data", {
                        "font-icon": data["font-icon"],
                        "color": hex,
                        "fontSize": fontSize
                    });
                }
            };
            setTimeout(function () {
                _this["iconForm"].find("#_icons").children("span").first().trigger("click");
            }, 1000);
        }
    }, params, this.setWindowColorPickerPosition);
    this.setWindowColorPickerPosition();
};
Kedit.prototype.showEmotionWindow = function (params, $btn) {
    this.openEmotionWindow("emotion", params, $btn);
};
Kedit.prototype.openEmotionWindow = function (method, params, $btn) {
    var _this = this;
    params["method"] = method;
    this.openWindow({
        title: eConfig.label.insertEmotion,
        width: 450,
        height: 200,
        contentFn: function (body, prs) {
            if (!_this["emotionForm"]) {
                _this["emotionForm"] = $("<div style='width:100%;height:100%;' class='k_box_size'></div>");
                if (typeof window.kemConfig !== 'undefined') {
                    var keys = Object.keys(window.kemConfig);
                    var closerTimer;
                    var _clickFn = function () {
                        clearTimeout(closerTimer);
                        var gif = $(this).attr("_gif");
                        prs["gif"] = gif;
                        var mName = params["method"];
                        _this.execute(mName, params);
                        closerTimer = setTimeout(function () {
                            _this.closeWindow();
                        }, 1500);
                    };
                    for (var i = 1, len = keys.length; i <= len; ++i) {
                        $("<div _gif='" + i + "' style='cursor:pointer;margin:4px;float:left;width:24px;height:24px;background:url(" + window.kemConfig[i] + ")'></div>")
                            .appendTo(_this["emotionForm"]).click(_clickFn);
                    }
                }
            }
            body.append(_this["emotionForm"]);
        }
    }, params);
};
Kedit.prototype.openCodeWindow = function (method, params) {
    var _this = this;
    params["method"] = method;
    var $b = _getBody();
    var w = $b.width() * 0.8;
    var h = $b.height() * 0.7;
    this.openWindow({
        title: eConfig.label.insertCode,
        width: w,
        height: h,
        contentFn: function (body, prs) {
            if (!_this["codeForm"]) {
                _this["codeForm"] = $(eConfig.codeForm);
                var $txt = _this["codeForm"].find("#k_code_input");
                _this["codeForm"].find("button").click(function () {
                    var v = $txt.html();
                    var preTag = _this["codeForm"].data("sourceTag");
                    if (preTag) {//执行更新                               
                        if ($.trim(v) === "") {
                            var $span = preTag.parent();
                            preTag.remove($span);
                            _this.moveToEnd();
                        } else {
                            preTag.html(v);
                        }
                        _this["codeForm"].removeData("sourceTag");
                    } else {//执行插入
                        prs["code"] = v;
                        var mName = params["method"];
                        _this.execute(mName, prs);
                    }
                    _this.closeWindow();
                });
                //动态加载脚本
                setTimeout(function () {
                    var $b = _this["codeForm"].parent();
                    var win = _this["window_iframe"][0].contentWindow;
                    var doc = $b[0].ownerDocument;
                    initCodeEditor(win, doc);
                }, 100);
            }
            var s = "<div>\u200B</div>";
            if (prs["sourceTag"]) {
                s = prs["sourceTag"].html();
                _this["codeForm"].data("sourceTag", prs["sourceTag"]);
                prs["sourceTag"] = undefined;
            } else {
                _this["codeForm"].removeData("sourceTag");
            }
            _this["codeForm"].find("#k_code_input").html(s);
            body.append(_this["codeForm"]);
        }
    }, params);
};
Kedit.prototype.openMapWindow = function (method, params, $btn) {
    var _this = this;
    var opts = eConfig.map;
    params["method"] = method;
    var mapPage = opts.page;
    this.openPageWindow({
        title: eConfig.label.insertMap,
        width: opts.windowSize.width,
        height: opts.windowSize.height,
        contentFn: function (body, prs, doc) {
            _this["mapForm"] = body;
            _this["pageWindow_iframe"].off("load");
            _this["pageWindow_iframe"].on("load", function () {
                _this["pageWindow_iframe"][0].contentWindow.setEdit(_this);
            });
            doc.location.href = mapPage;
        }
    }, params);
};
Kedit.prototype.showInsertFileWindow = function (params, $btn) {
    this.openInsertFileWindow("upload", params, $btn);
};
Kedit.prototype.openInsertFileWindow = function (method, params, $btn) {
    var _this = this;
    var opts = this.opts.uploadFile;
    if (!opts || !opts.url) {
        $B.message("please set the args [uploadFile] ");
        return;
    }
    params["method"] = method;
    this.openWindow({
        title: eConfig.label.insertFile,
        width: 500,
        height: 230,
        contentFn: function (body, prs) {
            if (!_this["fileForm"]) {
                _this["fileForm"] = $(eConfig.fileForm);
                _this["fileForm"].children("div").first().children("a").click(function () {
                    var $t = $(this);
                    var id = $t.attr("id");
                    var sibs = $t.parent().siblings("table").hide();
                    sibs.filter("#" + id + "form").show();
                    $t.siblings().css({
                        "color": "#666",
                        "background": "#fff"
                    });
                    $t.css({
                        "color": "#fff",
                        "background": "#666"
                    });
                });
                var inputWrap = _this["fileForm"].find("#_file_upload_wrap");
                var successFn = function (res) {
                    var params = _this["fileForm"].data("params");
                    var linkName = _this["fileForm"].find("#_link_name_").val();
                    if (res.data["linkName"] && linkName === "") {
                        linkName = res.data["linkName"];
                    }
                    params["linkName"] = linkName;
                    var url;
                    if ($.isPlainObject(res.data)) {
                        url = res.data.url;
                    } else {
                        url = res.data;
                    }
                    params["url"] = url;
                    _this.closeWindow();
                    var mName = params["method"];
                    var $a = _this.execute(mName, params);
                    if (opts.onSuccess) {
                        opts.onSuccess.call($a ,res);
                    }
                };
                var uploadCfg = {
                    target: inputWrap,
                    timeout: 200,
                    canDelete: true,
                    deleteClearFile: true,
                    url: undefined,
                    files: [{
                        name: '_k_edit_upolad_file',
                        type: '.*',
                        label: eConfig.label.selectFile
                    }],
                    immediate: false,
                    success: successFn,
                    onselected: function (srcFileName, name, accept) {
                        var nameInput = _this["fileForm"].find("#_link_name_");
                        if (nameInput.val() === "") {
                            nameInput.val(srcFileName);
                        }
                        return true;
                    },
                    error: opts.onError
                };
                uploadCfg.url = opts.url;
                if (opts.label) {
                    uploadCfg.files[0].label = opts.label;
                }
                if (opts.setParams) {
                    uploadCfg.setParams = opts.setParams;
                }
                var uploadObj = new $B.MutilUpload(uploadCfg);
                _this["fileForm"].data("uploadObj", uploadObj);
                _this["fileForm"].find("#_submit_upload_").click(function () {
                    var $btn = $(this);
                    var local = $btn.parent().siblings("#_local_upload_form");
                    if (local.css("display") === "table") {
                        $btn.data("uploadObj").submit();
                    } else {
                        var url = _this["fileForm"].find("#_addr_url").val();
                        if (url.indexOf("http") < 0) {
                            url = "http://" + url;
                        }
                        successFn({
                            data: {
                                url: url
                            }
                        });
                    }
                }).data("uploadObj", uploadObj);
            }
            _this["fileForm"].data("params", prs);
            body.append(_this["fileForm"]);
            var uploadTab = _this["fileForm"].children().first().children("#_local_upload_").trigger("click");
            _this["fileForm"].data("uploadObj").reset();
            _this["fileForm"].find("#_addr_url").val('');
            _this["fileForm"].find("#_link_name_").val('');
        }
    }, params);
};
Kedit.prototype.showInsertImageWindow = function (params, $btn) {
    this.openInsertImageWindow("picture", params, $btn);
};
Kedit.prototype.openInsertImageWindow = function (method, params, $btn) {
    var _this = this;
    var opts = this.opts.uploadImg;
    if (!opts || !opts.url) {
        $B.message("please set the args [uploadImg] ");
        return;
    }
    params["method"] = method;
    this.openWindow({
        title: eConfig.label.insertImage,
        width: 500,
        height: 310,
        contentFn: function (body, prs) {
            if (!_this["imageForm"]) {
                _this["imageForm"] = $(eConfig.imageForm);
                _this["imageForm"].children("div").first().children("a").click(function () {
                    var $t = $(this);
                    var id = $t.attr("id");
                    var sibs = $t.parent().siblings("table").hide();
                    sibs.filter("#" + id + "form").show();
                    $t.siblings().css({
                        "color": "#666",
                        "background": "#fff"
                    });
                    $t.css({
                        "color": "#fff",
                        "background": "#666"
                    });
                });
                _this["$imgPosition"] = _this["imageForm"].find("#_img_pos");
                _this["$imgWidth"] = _this["imageForm"].find("#_img_width");
                _this["$imgHeight"] = _this["imageForm"].find("#_img_height");
                _this["$autowidth"] =_this["imageForm"].find("#autowidth").click(function(){
                    var isChked = $(this).prop("checked");
                    if(isChked){
                        _this["$imgHeight"].attr("disabled","disabled").addClass("disabled_text_color");
                        _this["$imgWidth"].attr("disabled","disabled").addClass("disabled_text_color");
                    }else{
                        _this["$imgHeight"].removeAttr("disabled").removeClass("disabled_text_color");
                        _this["$imgWidth"].removeAttr("disabled").removeClass("disabled_text_color");
                    }
                });
                var as = _this["imageForm"].find(".k_edit_img_layout").children("a").click(function () {
                    var $t = $(this);
                    $t.siblings().removeClass("k_edit_img_pos_actived");
                    $t.addClass("k_edit_img_pos_actived");
                    _this["$imgPosition"].val($t.attr("v"));
                });
                _this["imagePosAct"] = as.eq(1);
                var inputWrap = _this["imageForm"].find("#_file_upload_wrap");

                var _rightPadding = _this["imageForm"].find("#_right_k_padding");
                var _topPadding = _this["imageForm"].find("#_top_k_padding");
                var _bottomPadding = _this["imageForm"].find("#_bottom_k_padding");
                var _leftPadding = _this["imageForm"].find("#_left_k_padding");
                var successFn = function (res) {
                    var params = _this["imageForm"].data("params");
                    var url;
                    if ($.isPlainObject(res.data)) {
                        url = res.data.url;
                    } else {
                        url = res.data;
                    }
                    params["url"] = url;
                    params["width"] = _this["$imgWidth"].val();
                    params["height"] = _this["$imgHeight"].val();
                    if (res.data["width"] && params["width"] === "") {
                        params["width"] = res.data["width"];
                    }
                    if (res.data["height"] && params["height"] === "") {
                        params["height"] = res.data["height"];
                    }
                    params["position"] = _this["$imgPosition"].val();
                    params["right"] = _rightPadding.val();
                    params["top"] = _topPadding.val();
                    params["bottom"] = _bottomPadding.val();
                    params["left"] = _leftPadding.val();
                    params["link"] = _this["imageForm"].find("#_href_").val();
                    params["isAuto"] =  _this["$autowidth"].prop("checked");
                    _this.closeWindow();
                    var mName = params["method"];
                    //console.log(params);
                    var $img = _this.execute(mName, params);
                    if (opts.onSuccess) {
                        opts.onSuccess.call($img,res);
                    }
                };
                var uploadCfg = {
                    target: inputWrap,
                    timeout: 200, //超时时间 秒
                    canDelete: true, //是否可以动态删除
                    deleteClearFile: true, //删除时候只清除文件
                    url: undefined,
                    // 待上传的文件列表，用于设置input的 name 以在服务器区分文件  	
                    files: [{
                        name: '_k_edit_upolad_file',
                        type: '.png,.gif,.jpg,jpeg',
                        label: eConfig.label.selectImg,
                        must: true
                    }],
                    onselected: function (value, id, accept) {
                        return true;
                    }, //选择文件后的事件请返回true 以便通过验证
                    immediate: false, //选择文件后是否立即自动上传，即不用用户点击提交按钮就上传
                    success: successFn,
                    error: opts.onError
                };
                uploadCfg.url = opts.url;
                if (opts.label) {
                    uploadCfg.files[0].label = opts.label;
                }
                if (opts.setParams) {
                    uploadCfg.setParams = opts.setParams;
                }
                var uploadObj = new $B.MutilUpload(uploadCfg);
                _this["imageForm"].data("uploadObj", uploadObj);
                _this["imageForm"].find("#_submit_upload_").click(function () {
                    var $btn = $(this);
                    var local = $btn.parent().siblings("#_local_upload_form");
                    if (local.css("display") === "table") {
                        $btn.data("uploadObj").submit();
                    } else {
                        var url = _this["imageForm"].find("#_addr_url").val();
                        if (url.indexOf("http") < 0) {
                            url = "http://" + url;
                        }
                        successFn({
                            data: {
                                url: url
                            }
                        });
                    }
                }).data("uploadObj", uploadObj);
            }
            var mName = prs["method"];
            _this["imageForm"].data("params", prs);
            _this["imagePosAct"].trigger("click");
            _this["imageForm"].data("uploadObj").reset();
            body.append(_this["imageForm"]);
            var uploadTab = _this["imageForm"].children().first().children("#_local_upload_").trigger("click");
            var uploadWrap = _this["imageForm"].find("#_local_upload_form");
            var _$right = _this["imageForm"].find("#_right_k_padding");
            var _$top = _this["imageForm"].find("#_top_k_padding");
            var _$bottom = _this["imageForm"].find("#_bottom_k_padding");
            var _$left = _this["imageForm"].find("#_left_k_padding");
            var alignAs = _this["imageForm"].find(".k_edit_img_layout").children("a");
            var hidePos = _this["imageForm"].find("#_img_pos");
            var linkAtrr = _this["imageForm"].find("#_href_");
            linkAtrr.val("");
            _this["$imgHeight"].removeAttr("disabled").removeClass("disabled_text_color");
            _this["$imgWidth"].removeAttr("disabled").removeClass("disabled_text_color");
            _this["$autowidth"].prop("checked",false);
            if (mName === "updateImage") { //更新
                var $img = prs.$img; 
                var imgCss = _this._style2CssObject($img);
                if(imgCss.width === "100%"){
                    _this["$autowidth"].prop("checked",true);
                    _this["$imgHeight"].addClass("disabled_text_color").prop("disabled",true);
                    _this["$imgWidth"].addClass("disabled_text_color").prop("disabled",true);
                }
                linkAtrr.val(prs.$img.attr("link"));
                alignAs.last().hide();
                uploadTab.next().hide();
                uploadTab.text(eConfig.label.imgUpdate);
                uploadWrap.hide();                              
                // _this["$imgPosition"].parent().hide();
                if(prs["$img"]){
                    _this["$imgWidth"].val(prs["$img"].width());
                    _this["$imgHeight"].val(prs["$img"].height());
                }else{
                    _this["$imgWidth"].val("");
                    _this["$imgHeight"].val("");
                }               
                var margins = prs["margin"].replace(/px/g, "").split(/\s+/);
                var _top = margins[0];
                var _right, _buttom, _left;
                if (margins.length === 1) {
                    _right = _top,
                        _buttom = _top,
                        _left = _top;
                } else if (margins.length === 2) {
                    _right = margins[1],
                        _buttom = _top,
                        _left = margins[1];
                } else {
                    _right = margins[1],
                        _buttom = margins[2],
                        _left = margins[3];
                }
                _$top.val(_top);
                _$right.val(_right);
                _$bottom.val(_buttom);
                _$left.val(_left);
                var align = prs["text-align"];
                alignAs.each(function () {
                    var $a = $(this);
                    var v = $a.attr("v");
                    if (v === align) {
                        $a.addClass("k_edit_img_pos_actived");
                        hidePos.val(v);
                    } else {
                        $a.removeClass("k_edit_img_pos_actived");
                    }
                });
            } else {
                alignAs.last().show();
                alignAs.each(function () {
                    var $a = $(this);
                    var v = $a.attr("v");
                    if (v === "left") {
                        hidePos.val("left");
                        $a.addClass("k_edit_img_pos_actived");
                    } else {
                        $a.removeClass("k_edit_img_pos_actived");
                    }
                });
                uploadTab.next().show();
                uploadTab.text(eConfig.label.localUplod);
                uploadWrap.show();
                // _this["$imgPosition"].parent().show();
                _this["$imgWidth"].val('');
                _this["$imgHeight"].val('');
                _$right.val(2);
                _$left.val(2);
                _$top.val(4);
                _$bottom.val(4);
            }
        }
    },
        params
    );
};
Kedit.prototype.showUploadVideo = function (method, params, $btn) {
    this.openUploadVideoWindow("uploadVideo", params);
};
Kedit.prototype.openUploadVideoWindow = function (method, params, $btn) {
    if (typeof videojs !== "function") {
        $B.alert(eConfig.label.videoWarning);
        return;
    }
    var _this = this;
    var opts = this.opts.uploadVideo;
    if (!opts || !opts.url) {
        $B.message("please set the args [uploadVideo] ");
        return;
    }
    params["method"] = method;
    this.openWindow({
        title: eConfig.label.insertVideo,
        width: 500,
        height: 280,
        contentFn: function (body, prs) {
            if (!_this["videoForm"]) {
                _this["videoForm"] = $(eConfig.videoForm);
                _this["videoForm"].children("div").first().children("a").click(function () {
                    var $t = $(this);
                    var id = $t.attr("id");//
                    if ("_remote_upload_" === id) {
                        _this["videoForm"].find("#_is_real_video").show();
                    } else {
                        _this["videoForm"].find("#_is_real_video").hide();
                    }
                    var sibs = $t.parent().siblings("table").hide();
                    sibs.filter("#" + id + "form").show();
                    $t.siblings().css({
                        "color": "#666",
                        "background": "#fff"
                    });
                    $t.css({
                        "color": "#fff",
                        "background": "#666"
                    });
                });
                _this["$videoWidth"] = _this["videoForm"].find("#_video_width");
                _this["$videoHeight"] = _this["videoForm"].find("#_video_height");
                var isPureVideoInput = _this["videoForm"].find("#_video_is");
                var inputWrap = _this["videoForm"].find("#_video_upload_wrap");
                var _rightPadding = _this["videoForm"].find("#_right_v_padding");
                var _topPadding = _this["videoForm"].find("#_top_v_padding");
                var _bottomPadding = _this["videoForm"].find("#_bottom_v_padding");
                var _leftPadding = _this["videoForm"].find("#_left_v_padding");
                var _repeat = _this["videoForm"].find("#_video_repeat");
                _this["videoForm"].find("#_addr_video").on("input", function () {
                    var $i = $(this);
                    var _v = $i.val().toLowerCase();
                    if (/\.(mp4|flv|f4v|ogv|webm)$/.test(_v)) {
                        isPureVideoInput.prop("checked", true);
                    } else {
                        isPureVideoInput.prop("checked", false);
                    }
                });
                var successFn = function (res) {
                    var params = _this["videoForm"].data("params");
                    var url;
                    if ($.isPlainObject(res.data)) {
                        url = res.data.url;
                    } else {
                        url = res.data;
                    }
                    if (res.message && res.message !== "") {
                        $B.success(res.message, 1.5);
                    }
                    params["data"] = url;
                    params["repeat"] = _repeat.prop("checked");
                    params["width"] = _this["$videoWidth"].val();
                    params["height"] = _this["$videoHeight"].val();
                    params["ispure"] = isPureVideoInput.prop("checked");
                    if (res.data["width"] && params["width"] === "") {
                        params["width"] = res.data["width"];
                    }
                    if (res.data["height"] && params["height"] === "") {
                        params["height"] = res.data["height"];
                    }
                    params["right"] = _rightPadding.val();
                    params["top"] = _topPadding.val();
                    params["bottom"] = _bottomPadding.val();
                    params["left"] = _leftPadding.val();
                    _this.closeWindow();
                    var mName = params["method"];
                    var $v = _this.execute(mName, params);
                    if (opts.onSuccess) {
                        opts.onSuccess.call($v,res);
                    }
                };
                var uploadCfg = {
                    target: inputWrap,
                    timeout: 200, //超时时间 秒
                    canDelete: true, //是否可以动态删除
                    deleteClearFile: true, //删除时候只清除文件
                    url: undefined,
                    // 待上传的文件列表，用于设置input的 name 以在服务器区分文件  	
                    files: [{
                        name: '_k_edit_upolad_file',
                        type: '.flv,.f4v,.mp4,.ogv,.webm',
                        label: eConfig.label.selectVideo,
                        must: true
                    }],
                    onselected: function (value, id, accept) {
                        return true;
                    }, //选择文件后的事件请返回true 以便通过验证
                    immediate: false, //选择文件后是否立即自动上传，即不用用户点击提交按钮就上传
                    success: successFn,
                    error:opts.onError
                };
                uploadCfg.url = opts.url;
                if (opts.label) {
                    uploadCfg.files[0].label = opts.label;
                }
                if (opts.setParams) {
                    uploadCfg.setParams = opts.setParams;
                }
                var uploadObj = new $B.MutilUpload(uploadCfg);
                _this["videoForm"].data("uploadObj", uploadObj);
                _this["videoForm"].find("#_submit_upload_").click(function () {
                    var $btn = $(this);
                    var local = $btn.parent().siblings("#_local_upload_form");
                    if (local.css("display") === "table") {
                        $btn.data("uploadObj").submit();
                    } else {
                        var url = _this["videoForm"].find("#_addr_video").val();
                        if (url.indexOf("http") < 0) {
                            url = "http://" + url;
                        }
                        successFn({
                            data: {
                                url: url
                            }
                        });
                    }
                }).data("uploadObj", uploadObj);
            }
            var mName = prs["method"];
            _this["videoForm"].data("params", prs);
            _this["videoForm"].data("uploadObj").reset();
            body.append(_this["videoForm"]);
            var uploadTab = _this["videoForm"].children().first().children("#_local_upload_").trigger("click");
            var uploadWrap = _this["videoForm"].find("#_local_upload_form");
            var _$right = _this["videoForm"].find("#_right_v_padding");
            var _$top = _this["videoForm"].find("#_top_v_padding");
            var _$bottom = _this["videoForm"].find("#_bottom_v_padding");
            var _$left = _this["videoForm"].find("#_left_v_padding");
            if (mName === "updateVideo") { //更新
                uploadTab.next().hide();
                uploadTab.text(eConfig.label.videoUpdate);
                uploadWrap.hide();
                _this["$videoWidth"].val(prs["width"]);
                _this["$videoHeight"].val(prs["height"]);
                var margins = prs["margin"].replace(/px/g, "").split(/\s+/);
                var _top = margins[0];
                var _right, _buttom, _left;
                if (margins.length === 1) {
                    _right = _top,
                        _buttom = _top,
                        _left = _top;
                } else if (margins.length === 2) {
                    _right = margins[1],
                        _buttom = _top,
                        _left = margins[1];
                } else {
                    _right = margins[1],
                        _buttom = margins[2],
                        _left = margins[3];
                }
                _$top.val(_top);
                _$right.val(_right);
                _$bottom.val(_buttom);
                _$left.val(_left);
            } else {
                uploadTab.next().show();
                uploadTab.text(eConfig.label.localUplod);
                uploadWrap.show();
                _this["$videoWidth"].val('');
                _this["$videoHeight"].val('');
                _$right.val(2);
                _$left.val(2);
                _$top.val(4);
                _$bottom.val(4);
            }
        }
    },
        params
    );
};
Kedit.prototype.updateVideo = function (params) {
    var $pre = params.$pre;
    var bottom = params.bottom;
    var top = params.top;
    var left = params.left;
    var right = params.right;
    var data = JSON.parse($pre.attr("data"));
    data.loop = params.repeat;
    data.height = parseInt(data.height);
    data.width = parseInt(data.width);
    var margin = [top + "px", right + "px", bottom + "px", left + "px"];
    $pre.css("margin", margin.join(" "));
    if (data.width !== params.width || data.height !== params.height) {
        data.width = params.width;
        data.height = params.height;
        if ($pre.hasClass("k_video_url")) {
            $pre.children("div").css({ width: data.width, height: data.height });
        } else {
            var player = $pre.data("player");
            player.width(data.width);
            player.height(data.height);
        }
    }
    if (!$pre.hasClass("k_video_url")) {
        $pre.attr("data", JSON.stringify(data));
    }
};
/***
 * finished 2019-02-25 23:00
 * 上传视频支持：依赖videojs，支持本地视频、远程视频（iframe页面/纯视频ur）
 * params = {
 *      width : 视频宽度
 *      height: 视频高度
 *      repeat : 是否循环播放
 *      ispure : 纯视频url(即非网页嵌入式视频)
 *      data：url / 数组[{ url: xxx ,type: video/mp4 }]
 * }
 * ****/
Kedit.prototype.uploadVideo = function (params) {
    var range = this.range;
    if (!range) {
        return;
    }
    var id = getUUID();
    var width = params.width === "" ? 320 : params.width,
        height = params.height === "" ? 240 : params.height;
    if (params.top === "") {
        params.top = 2;
    }
    if (params.right === "") {
        params.right = 2;
    }
    if (params.bottom === "") {
        params.bottom = 2;
    }
    if (params.left === "") {
        params.left = 2;
    }
    var margin = {
        "margin-top": params.top + "px",
        "margin-right": params.right + "px",
        "margin-bottom": params.bottom + "px",
        "margin-left": params.left + "px"
    };
    var videoParams = {
        muted: true,
        controls: true,
        height: height,
        width: width,
        loop: params.repeat
    };
    var $ifr;
    var insertTag = this._getInsertP();
    insertTag.children().remove();
    var $video, nextPelement, videoHtml, isVideoJs = false;
    var source = [];
    if ($.isArray(params.data)) {//本地上传
        isVideoJs = true;
        var videoUrl;
        for (var i = 0, len = params.data.length; i < len; ++i) {
            if (!videoUrl) {
                videoUrl = params.data[i].url;
            }
            source.push('<source src="' + params.data[i].url + '" type="' + params.data[i].type + '"></source>');
        }
        videoHtml = eConfig.videoHtml.replace(/_\$video_url\$_/g, videoUrl).replace("my_video_id", id).replace("_$source$_", source.join(""));
    } else {//url方式
        var ispure = params.ispure;
        if (ispure) {
            var videoType;
            var vurl = params.data.toLowerCase();
            if (vurl.indexOf(".mp4") > 0) {
                videoType = 'video/mp4';
            } else if (vurl.indexOf(".ogg") > 0) {
                videoType = 'video/ogg';
            } else if (vurl.indexOf(".webm") > 0) {
                videoType = 'video/webm';
            }
            if (!videoType) {
                $B.alert("not support type!");
                return;
            }
            isVideoJs = true;
            videoUrl = params.data;
            source.push('<source src="' + videoUrl + '" type="' + videoType + '"></source>');
            videoHtml = eConfig.videoHtml.replace(/_\$video_url\$_/g, videoUrl).replace("my_video_id", id).replace("_$source$_", source.join(""));
        } else {
            var remotePre = $('<pre contenteditable="false" style="padding: 1px; margin:2px;" class="k_video_pre k_video_url"><div class="k_video_ifr_wrap" style="overflow:hidden;"><iframe scrolling="no" class="panel_content_ifr" frameborder="0" style="overflow:visible;height:100%;width:100%;display:block;vertical-align:top;" ></iframe></div></pre>');
            $ifr = remotePre.children("div").css({
                width: width,
                height: height,
                'padding-top': margin["margin-top"],
                'padding-right': margin["margin-right"],
                'padding-bottom': margin["margin-bottom"],
                'padding-left': margin["margin-left"]
            }).children("iframe");
            videoHtml = remotePre[0].outerHTML;
        }
    }
    if (this.clickActivedObject && this.clickActivedObject.className === "table") {
        var createNextPle = false;
        var clickTd = this.clickActivedObject.clickTd;
        if (!clickTd && this.range) {
            var acontainer = this.range.commonAncestorContainer;
            if (acontainer.nodeType === 3) {
                acontainer = $(acontainer.parentNode);
            } else {
                acontainer = $(acontainer);
            }
            while (acontainer.length > 0) {
                if (acontainer[0].tagName === "TD") {
                    clickTd = acontainer;
                    break;
                }
                acontainer = acontainer.parent();
            }
        }
        if (clickTd) {//插入表格td中                    
            clickTd.html(videoHtml);
            this.clickActivedObject.reSize();
            this.clickActivedObject.reSize(true);//设置大小 
            $video = clickTd.children("pre");
        }
    } else {
        createNextPle = true;
        insertTag.append(videoHtml);
        $video = insertTag.children("pre");
    }
    if (isVideoJs) {
        $video.css(margin);
        this._createVideoPlayer($video, videoParams);
    } else {
        $ifr = $video.find("iframe");
        var ifr = $ifr[0];
        ifr.src = params.data;
    }
    if (createNextPle) {
        nextPelement = insertTag.next();
        if (nextPelement.length === 0) {
            nextPelement = this.insertPElement();
        }
    }
    var _this = this;
    setTimeout(function () {
        _this._bindVideoEvents($video);
        if (nextPelement) {
            _this.moveToEnd(nextPelement);
        }
    }, 10);
    return $video;
};
/**
* 创建videojs的 player
* **/
Kedit.prototype._createVideoPlayer = function ($preJq, videoParams) {
    if ($preJq.length === 0 || $preJq[0].tagName !== "PRE") {
        return;
    }
    var domEl = $preJq.children(".video-js");
    var id, videoEl;
    if (domEl.length === 1 && domEl[0].tagName === "DIV") {//移除
        videoEl = domEl.children("video");
        videoEl.detach().insertAfter(domEl);
        domEl.remove();
        id = videoEl.attr("id");
    } else if (domEl[0].tagName === "VIDEO") {
        id = domEl.attr("id");
        videoEl = domEl;
    }
    id = id.replace("_html5_api", "");
    videoEl.attr("id", id);
    var prop = $preJq.attr("data");
    if (prop) {
        prop = prop.replace(/&quot;/g, "\"");
        videoEl.attr("data-setup", prop);
    }
    videoEl.addClass("video-js vjs-default-skin vjs-big-play-centered");
    var video = window["videojs"];
    //避免重复创建时候 存在相同的video实例
    var players = video.getPlayers();
    if (players) {
        for (var p in players) {
            if (players.hasOwnProperty(p) && p === id) {
                delete players[p];
            }
        }
    }
    $preJq.attr("data", JSON.stringify(videoParams));
    var player = video(id, videoParams);
    $preJq.data("player", player);
};
/***
* 绑定视频事件
* ***/
Kedit.prototype._bindVideoEvents = function (el) {
    var _this = this;
    var $video;
    var firstEl = el.children().first();
    if (firstEl[0].tagName === "VIDEO") {
        $video = firstEl;
    } else {
        if (firstEl.hasClass("video-js")) {
            $video = firstEl.children("video");
        } else {
            $video = el;//frame嵌入的视频,只能操作pre元素，
        }
    }
    //兼容外部插入视频场景           
    $video.mouseup(function (e) {
        if (e.which === 3) {
            var $t = $(this);
            var self = $t.parent();
            if (self[0].tagName === "DIV" && !self.hasClass("_section_div_")) {
                self = self.parent();
            }
            var pEl = self;
            if (!self.hasClass("_section_div_")) {
                pEl = self.parent();
            }
            while (pEl.length > 0) {
                if (pEl[0].tagName === "DIV") {
                    break;
                }
                pEl = pEl.parent();
            }
            var me = _this;
            me.startPElement = pEl;
            me.endPElement = pEl;
            me.openTIPWindow({
                top: e.pageY,
                left: e.pageX,
                $pre: self
            }, function (body, prs) {
                if (!me["preViTip"]) { //                           
                    me["preViTip"] = $("<div><p class='_modifySection' style='cursor:pointer;'><i style='padding-right:4px;' class='fa fa-exchange'></i>" + eConfig.label.setSectionWidth + "</p>" +
                        "<p class='_resetSection' style='cursor:pointer;display:none;'><i style='padding-right:4px;' class='fa fa-resize-horizontal'></i>" + eConfig.label.resetSectionWidth + "</p>" +
                        "<p class='_delete_imag' style='cursor:pointer;'><i class='fa fa-cancel' style='padding-right:4px;'></i>" + eConfig.label.delete + "</p>" +
                        "<p class='_modifyedit' style='cursor:pointer;'><i class='fa fa-edit-1' style='padding-right:4px;'></i>" + eConfig.label.modify + "</p>" +
                        "<p class='_modifymove' style='cursor:pointer;'><i class='fa fa-move' style='padding-right:4px;'></i>" + eConfig.label.move + "</p></div>");
                    var $mody = me["preViTip"].children("p._modifyedit").click(function () {
                        var tip = $(this).parent();
                        tip.parent().parent().hide();
                        var pre = tip.data("$pre");
                        var $video = pre.children().children("video");
                        var params = {
                            height: $video.height(),
                            width: $video.width(),
                            margin: pre.css("margin"),
                            $pre: pre
                        };
                        me.openUploadVideoWindow("updateVideo", params);
                    });
                    if ($t.hasClass("k_video_url")) {//远程url视频
                        $mody.hide();
                    } else {
                        $mody.show();
                    }
                    me["preViTip"].children("p._modifySection").click(function () {
                        me.setSectionWidth();
                        me["preViTip"].detach();
                        me["tipWindow"].hide();
                    });
                    me["preViTip"].children("p._resetSection").click(function () {
                        me.resetSectionWidth();
                        me["preViTip"].detach();
                        me["tipWindow"].hide();
                    });
                    me["preViTip"].children("p._delete_imag").click(function () {
                        var tip = $(this).parent();
                        me.resizeBox.hide();
                        me.resizeBox.target = undefined;
                        if (me.movingAcn) {
                            me.movingAcn.hide();
                        }
                        tip.parent().parent().hide();
                        var pre = tip.data("$pre");
                        me._putUndoDataByNodeEl(pre);
                        var pel;
                        if (pre.hasClass("_section_div_")) {//兼容外部url视频
                            pel = pre;
                            pre.children().remove();
                        } else {
                            pel = pre.parent();
                            pre.remove();
                        }
                        tip.removeData("$pre");
                        if (pel.children().length === 0) {
                            me._getSpan().appendTo(pel);
                        }
                        me.moveToEnd(pel);
                        if (me.opts.onDeleted) {
                            me.opts.onDeleted.call(pre, pre.children("div").attr("src"));
                        }
                    });
                    me["preViTip"].children("p._modifymove").click(function () {
                        var tip = $(this).parent();
                        tip.parent().parent().hide();
                        var pre = tip.data("$pre");
                        var pEl;
                        if (pre.hasClass("_section_div_")) {//兼容外部url视频
                            pEl = pre;
                        } else {
                            pEl = pre.parent();
                            while (pEl.length > 0) {
                                if (pEl[0].tagName === "DIV") {
                                    break;
                                }
                                pEl = pEl.parent();
                            }
                        }
                        me._setMovingTargets([pEl], false);
                    });
                }
                var $_pre = prs["$pre"];
                if (me.startPElement.css("padding-left") !== "0px") {
                    me["preViTip"].children("p._resetSection").show();
                } else {
                    me["preViTip"].children("p._resetSection").hide();
                }
                me["preViTip"].data("$pre", $_pre);
                body.append(me["preViTip"]);
                if (pEl.parent().hasClass("k_editor_float_input")) {
                    me["preViTip"].children("p._modifymove").hide();
                } else {
                    me["preViTip"].children("p._modifymove").show();
                }
            });
            me._setMovingTargets([pEl], false, function () {
                me["tipWindow"].hide();
            });
            var $modifyIt = me["preViTip"].children("p._modifyedit");
            //大小拖动功能
            var box;
            if ($t.hasClass("k_video_url")) {//远程url视频
                box = $t.children("div");
                $modifyIt.hide();
            } else {
                box = self.children("div").children("video");
                $modifyIt.show();
            }
            me._createResizeBox(box);
        }
        return false;
    });
};
/***
 * 标题功能
 * ***/
Kedit.prototype.fontTitle = function (params, $btn) {
    console.log("fontTitle  >>>>" + JSON.stringify(params["font-title"]));
    var css = params["font-title"];
    this.foreachPTargets(function (p) {
        p.css({
            "line-height": css["line-height"]
        }).children("span").each(function () {
            $(this).css({
                "font-weight": css["font-weight"],
                "font-size": css["font-size"]
            });
        });
    });
};


/**向下折叠**/
Kedit.prototype.closedNext = function (params, $btn) {
    var sectionEl = this.getAnchorSectionEl();
    var countClosed = sectionEl.attr("closed_count");
    if (countClosed) {
        sectionEl.removeClass("_section_div_close_title").removeAttr("closed_count").removeAttr("closed_status");
        return;
    }
    var _this = this;
    this.openWindow({
        title: eConfig.label.closedCfg,
        width: 400,
        height: 200,
        contentFn: function (body, prs) {
            if (!_this["closedForm"]) {
                _this["closedForm"] = $(eConfig.closedForm);
                _this["closedForm"].find("#_section_c").on("change", function () {
                    var v = parseInt($(this).val());
                    var anchor = _this.getAnchorSectionEl();
                    var next = anchor.next("._section_div_");
                    while (next.length > 0 && next.hasClass("k_editor_closed_section")) {
                        next.removeClass("k_editor_closed_section").removeClass("_section_div_close_title");
                        next = next.next();
                    }
                    _this.closedSections = [];
                    var nextSection = anchor.next("._section_div_");
                    while (v > 0) {
                        if (nextSection.length > 0) {
                            _this.closedSections.push(nextSection);
                            nextSection.addClass("k_editor_closed_section");
                            nextSection = nextSection.next("._section_div_");
                        }
                        v--;
                    }
                });
                _this["closedForm"].find("button").click(function () {
                    var chk = _this["closedForm"].find("input[name='_status']:checked").val();
                    var pEl = _this.getAnchorSectionEl();
                    pEl.addClass("_section_div_close_title").attr("closed_count", _this.closedSections.length);
                    if (chk === "0") {
                        pEl.attr("closed_status", "true");
                    } else {
                        pEl.removeAttr("closed_status");
                    }
                    _this.closeWindow();
                });
            }
            var anchorPel = _this.getAnchorSectionEl();
            _this.closedSections = [];
            var $el = anchorPel.next().addClass("k_editor_closed_section"); //_section_div_close_title
            _this.closedSections.push($el);
            _this["closedForm"].find("#_section_c").val("1");
            body.append(_this["closedForm"]);
        }
    });
};
/**根据id删除table**/
Kedit.prototype._deleteTable = function (deleteTableId) {
    var _this = this;
    var arr = [];
    var deleteObj;
    for (var i = 0, len = _this.tables.length; i < len; ++i) {
        if (deleteTableId !== _this.tables[i].id) {
            arr.push(_this.tables[i]);
        } else {
            deleteObj = _this.tables[i];
        }
    }
    _this.tables = arr;
    if (deleteObj) {
        if (deleteObj === this.clickActivedObject) {
            this.clickActivedObject = undefined;
        }
        deleteObj.remove();
    }
};
/**清除选择的td记录**/
Kedit.prototype.clearSelectedTd = function () {
    this.cssTdArray = undefined;
};
/**
 * 表格修饰
 * ***/
Kedit.prototype.tableCss = function (method, params, button) {
    var cssTdArray = this.clickActivedObject.selectTdArray;
    var css2Td = method.indexOf("align") > -1;
    var collapsed = this._getDomRangeOnly().collapsed;
    if (collapsed) {
        css2Td = true;
    }
    if (css2Td && cssTdArray.length > 0) { //对齐修饰,修改修饰目标
        this._removePainTargets();
        var _this = this;
        var loopFn = function (ele) {
            _this.painTargets.push(ele);
            ele.children().each(function () {
                loopFn($(this));
            });
        };
        for (var i = 0, len = cssTdArray.length; i < len; ++i) {
            var td = cssTdArray[i];
            loopFn(td);
        }
        if (params["css"]) {
            this.css(params["css"]);
        } else {
            this[method](params, button);
        }
        return false;
    }
    return true;
};
/**保存**/
Kedit.prototype.save = function (params, button) {
    if (button.attr("disabled") || button.hasClass("disabled")) {
        return;
    }
    if (this.opts.onSave) {
        var res = this.getContent();
        this.opts.onSave.call(button, res, encodeURIComponent(res));
    }
};
/**格式刷**/
Kedit.prototype.paintBrush = function (prs, button) {
    var brushPel = this.startPElement;
    var seqData = this._getSectionSeqDatas(brushPel);
    if (seqData.isSeq) {
        this.brushSeqData = seqData;
    }
    var _this = this;
    $B.confirm({
        message: eConfig.label.brushmessage,
        width: 350,
        height: 120,
        title: eConfig.label.brushopts,
        okIcon: 'fa-ok-circled',
        noIcon: 'fa-minus-circled',
        okText: eConfig.label.yes,
        noText: eConfig.label.no,
        okFn: function () {
            _this.brushCss = _this._getRangeCss(true, true);
            _this.activedMenu = button.addClass("k_edit_btn_actived");
        },
        noFn: function () {
            _this.brushCss = _this._getRangeCss(true);
            _this.activedMenu = button.addClass("k_edit_btn_actived");
        }
    });
};
/**将样式刷到目标元素**/
Kedit.prototype.brush2Target = function () {
    this._clearRangeRecord();
    this.saveUserRange();
    this.setPaintTarget();
    var css, key, putUndo = false;
    var pCss = this.brushCss.pCss;//段落样式
    delete this.brushCss.pCss;
    if (pCss) {
        this.ignorePele = true;
        this.foreachPTargets(function (p) {
            p.css(pCss);
        });
    }
    var newCss = this.brushCss;
    if (!this.range.collapsed) {
        this._makeUndoDataByFocus();
        var cssKeys = Object.keys(this.brushCss);
        for (var i = 0, len = cssKeys.length; i < len; ++i) {
            css = {};
            key = cssKeys[i];
            css[key] = this.brushCss[key];
            if (css[key]) {
                this.css(css);
                putUndo = true;
            }
        }
    }
    this.activedMenu.removeClass("k_edit_btn_actived");
    this.brushCss = undefined;
    this.ignorePele = undefined;
    // 序列支持，只支持单个段落刷为相同序列
    if (this.brushSeqData) {
        if (this.startPElement[0] === this.endPElement[0]) {
            var linkSeqChain = [];
            var pEl = this.brushSeqData.seqEl.parent().next();
            var seqData = this.brushSeqData,
                tmpSeqData, nextSeqNum;
            var currentSeqIndex, nextSeqIndex;
            if (seqData.isChSeq) {
                currentSeqIndex = getChSeqIndex(seqData.seqNum);
            } else {
                currentSeqIndex = seqData.seqNum;
            }
            linkSeqChain.push(seqData.seqNum);
            while (pEl.length > 0) {
                tmpSeqData = this._getSectionSeqDatas(pEl);
                if (!tmpSeqData.isSeq) {
                    break;
                }
                if (this._isSameSeq(seqData.seqNumTxt, tmpSeqData.seqNumTxt, seqData.seqEl, tmpSeqData.seqEl)) {
                    //判断是否是相同连续序列
                    if (tmpSeqData.isChSeq) {
                        nextSeqIndex = getChSeqIndex(tmpSeqData.seqNum);
                    } else {
                        nextSeqIndex = tmpSeqData.seqNum;
                    }
                    if (currentSeqIndex !== nextSeqIndex - 1) {
                        break;
                    }
                    linkSeqChain.push(tmpSeqData.seqNum);
                    seqData = tmpSeqData;
                    pEl = pEl.next();
                    currentSeqIndex = nextSeqIndex;
                } else {
                    break;
                }
            }
            var seqSpan;
            var isNewSpan = false;
            var nextChSeqIndex;
            var existSeqData = this._getSectionSeqDatas(this.startPElement);
            var isUpdateSeq = true;
            if (existSeqData.isSeq) {
                for (var i1 = 0, len1 = linkSeqChain.length; i1 < len1; ++i1) {
                    if (linkSeqChain[i1] === existSeqData.seqNum) {//在一个连续的序列里面 不需要更新序列
                        isUpdateSeq = false;
                        break;
                    }
                }
                seqSpan = existSeqData.seqEl;
            } else {
                seqSpan = this._getSpan();
                isNewSpan = true;
            }
            if (isUpdateSeq) {
                if (seqData.isChSeq) {
                    nextSeqNum = getChNextSeq(seqData.seqNum);
                    seqSpan.html(seqData.seqNumTxt.replace(seqData.seqNum, nextSeqNum.seq));
                    nextChSeqIndex = nextSeqNum.index;
                } else {
                    nextSeqNum = seqData.seqNum + 1;
                    seqSpan.html(seqData.seqNumTxt.replace(/\d+/g, nextSeqNum));
                }
                if (isNewSpan) {
                    this.startPElement.prepend(seqSpan);
                }
                seqSpan.css(newCss);
                var cureSeqData = this._getSectionSeqDatas(this.startPElement);
                var nextEle = this.startPElement.next();
                var nextSeqData, chSeq;
                while (nextEle.length > 0) {
                    nextSeqData = this._getSectionSeqDatas(nextEle);
                    if (!nextSeqData.isSeq) {
                        break;
                    }
                    if (this._isSameSeq(cureSeqData.seqNumTxt, nextSeqData.seqNumTxt, cureSeqData.seqEl, nextSeqData.seqEl)) {
                        if (nextSeqData.isChSeq) {
                            nextChSeqIndex++;
                            chSeq = chSeqArray[nextChSeqIndex];
                            nextSeqData.seqEl.html(nextSeqData.seqNumTxt.replace(nextSeqData.seqNum, chSeq));
                        } else {
                            nextSeqNum++;
                            nextSeqData.seqEl.html(nextSeqData.seqNumTxt.replace(/\d+/g, nextSeqNum));
                        }
                    } else {
                        break;
                    }
                    nextEle = nextEle.next();
                }
            }
        }
    }
    this.brushSeqData = undefined;
    if (putUndo) {
        this._putUndo();
    }
    this["undoRedoRec"] = undefined;
};

/***
 * 清空
 * * */
Kedit.prototype.clear = function () {
    this._hideOthersIcon();
    for (var i = 0, len = this.tables.length; i < len; ++i) {
        if (this.tables[i].remove) {
            this.tables[i].remove();
        }
    }
    this.$inputWrap.children(".k_edit_float_panel").remove();
    this.tables = [];
    var firstP = this.$input.children("div").first();
    var id = getUUID();
    firstP.html('<span style="' + eConfig.defaultStyle + '" id="' + id + '">\u200B</span>');
    firstP.nextAll().remove();
    firstP.removeAttr("contenteditable");
    this.moveToEnd(firstP);
    firstP.css(eConfig.pElementCss);
    _getBody().children("#k_edit_table_anchor").hide();
    if (this.sectionResizeBar) {
        this.sectionResizeBar.remove();
    }
    if (this.sectionResizeBar2) {
        this.sectionResizeBar2.remove();
    }
    if (this.movingAcn) {
        this.movingAcn.hide();
    }
};
/**源码/视图**/
Kedit.prototype.source = function (prs, button) {
    var sections = this.$input.children("div");
    if (!this["sourceView"]) {
        this["sourceView"] = $('<textarea class="k_box_size" style="display:none; width:100%;height:98%;resize: none; border: 0px; padding: 0px; margin: 0px; overflow-y: auto; outline: 0px;" />');
    }
    var display = this["sourceView"].css("display");
    if (display === "none") {
        button.addClass("k_edit_btn_actived");
        var contents = [];
        sections.each(function () {
            var $s = $(this);
            contents.push($s[0].outerHTML);
            contents.push("\n");
        });
        this.$inputWrap.children(".k_edit_float_panel").each(function () {
            contents.push($(this)[0].outerHTML);
            contents.push("\n");
        });
        this["sourceView"].val(contents.join("")).show();
        this.$input.hide();
        this["sourceView"].insertAfter(this.$input);
        this.clearUserRange(true);
        this.$inputWrap.children(".k_edit_float_panel").hide();
        if (this.floatTools) {
            this.floatTools.hide();
        }
        if (this.floatPropPanel) {
            this.floatPropPanel.hide();
        }
        this.closeAllWindow();
    } else {
        button.removeClass("k_edit_btn_actived");
        this["sourceView"] = this["sourceView"].remove().hide().val('');
        this.$input.show();
        this.$inputWrap.children(".k_edit_float_panel").show();
        this.moveToEnd(this.$input.children().last());
    }
};
/**字体间距 letter-spacing**/
Kedit.prototype.fontSpace = function (params) {
    var cmd = params.cmd;
    var user2 = params.user2;
    //console.log("user2 = "+user2);
    var fn = function ($i, i) {
        if (cmd === "reset") {
            $i.css("letter-spacing", "0px");
        } else {
            var l = $i.css("letter-spacing");
            if (!l) {
                l = "0px";
            } else {
                l = parseInt(l.replace("px", ""));
            }
            if (cmd === "accretion") {
                $i.css("letter-spacing", ++l);
            } else if (cmd === "reduce") {
                $i.css("letter-spacing", --l);
            }
        }
    };
    if (user2 === "1") {
        this.foreachTargets(fn);
    } else {
        this.foreachPTargets(fn);
    }
};
/***插入表格***/
Kedit.prototype.insertTable = function (params) {
    var col = params["col"];
    var row = params["row"];
    var range = this.range;
    if (!range) {
        return;
    }
    var container = this.endPElement;
    if (!container) {
        var ancContainer = range.commonAncestorContainer;
        if (ancContainer.nodeType === 3) {
            ancContainer = ancContainer.parentNode;
        }
        container = $(ancContainer);
        if (container[0].tagName !== sectionTag) {
            container = container.parent();
            while (container[0].tagName !== sectionTag) {
                container = container.parent();
            }
        }
    }
    //var childs = container.children();
    var txt = container.text();
    var isEmpty = txt === "" || txt === "\u200B";
    if (!isEmpty) {
        container = this.insertPElement(container);
    }
    container.html("");
    var table = new Table(this).init(col, row);
    table.jqObj.attr("id", getUUID());
    this.tables.push(table);
    table.appendTo(container);
    container.children("br").remove();
    var firstTd = table.tbody.children().first().children().first();
    var _this = this;
    if (container.next().length === 0) {
        var $p = this.createPElement();
        $p.insertAfter(container);
    }
    this.createCrossRange(firstTd, firstTd);
};

/**加粗**/
Kedit.prototype.bold = function (params) {
    var curValue = this.getCurrentCssValue("font-weight");
    if (curValue === "400" || !curValue) {
        this.css({
            "font-weight": "bold"
        });
    } else {
        this.css({
            "font-weight": "normal"
        });
    }
};
/**斜体**/
Kedit.prototype.italic = function (params) {
    var curValue = this.getCurrentCssValue("font-style");
    if (curValue && curValue === "normal") {
        this.css({
            "font-style": "italic"
        });
    } else {
        this.css({
            "font-style": "normal"
        });
    }
};
/**
 * 下划线
 * **/
Kedit.prototype.underline = function (params) {
    var curValue = this.getCurrentCssValue("text-decoration");
    var _this = this;
    if (curValue && curValue.indexOf("none") < 0 && curValue.indexOf("line-through") < 0) {
        this.css(function (jqObj) {
            _this.cssing = {
                "text-decoration": "none"
            };
            jqObj.css(_this.cssing);
            var $p = jqObj.parent();
            if ($p[0].tagName !== "DIV") {
                var css = _this._getCopyStyle($p);
                delete css["text-decoration"];
                $p.removeAttr("style").css(css);
            }
        });
    } else {
        this.css(function (jqObj) {
            _this.cssing = {
                "text-decoration": "underline"
            };
            jqObj.css(_this.cssing);
        });
    }
};
/***
 * 删除线
 * ***/
Kedit.prototype.strikethrough = function (params) {
    var curValue = this.getCurrentCssValue("text-decoration");
    if (curValue && curValue.indexOf("none") < 0 && curValue.indexOf("underline") < 0) {
        this.css({
            "text-decoration": "none"
        });
    } else {
        this.css({
            "text-decoration": "line-through"
        });
    }
};
/**上标 * **/
Kedit.prototype.superscript = function (params) {
    var _this = this;
    this.foreachTargets(function ($t, i) {
        var verticalAlign = $t.css("vertical-align");
        if (verticalAlign && verticalAlign === "super") {
            var css = _this._getCopyStyle($t.parent());
            var fontSize = css["font-size"];
            var newCss = _this._getCopyStyle($t);
            newCss["font-size"] = fontSize;
            delete newCss["vertical-align"];
            $t.removeAttr("style");
            $t.css(newCss);
        } else {
            $t.css({
                "vertical-align": "super",
                "font-size": "smaller"
            });
        }
    });
};
/**下标**/
Kedit.prototype.subscript = function (params) {
    var _this = this;
    this.foreachTargets(function ($t, i) {
        var verticalAlign = $t.css("vertical-align");
        if (verticalAlign && verticalAlign === "sub") {
            var css = _this._getCopyStyle($t.parent());
            var fontSize = css["font-size"];
            var newCss = _this._getCopyStyle($t);
            newCss["font-size"] = fontSize;
            delete newCss["vertical-align"];
            $t.removeAttr("style");
            $t.css(newCss);
        } else {
            $t.css({
                "vertical-align": "sub",
                "font-size": "smaller"
            });
        }
    });
};
/**字体**/
Kedit.prototype.fontFamily = function (params) {
    var fontFamily = params["font-family"];
    this.css({
        "font-family": fontFamily
    });
};
/**字体颜色**/
Kedit.prototype.fontColor = function (params) {
    this.css({
        color: params.color
    });
    this.changeSelectionColor("color", params.color);
};
/**背景色**/
Kedit.prototype.backgroundColor = function (params) {
    this.css({
        "background-color": params.color
    });
    var range = this.getDomRange();
    var collapsed = range.collapsed;
    if (collapsed) {
        var ancContainer = range.commonAncestorContainer;
        if (ancContainer.nodeType === 3) {
            ancContainer = ancContainer.parentNode;
        }
        ancContainer = $(ancContainer);
        var td;
        while (ancContainer.length > 0) {
            if (ancContainer.hasClass("_section_div_")) {
                break;
            }
            if (ancContainer[0].tagName === "TD") {
                td = ancContainer;
                break;
            }
            ancContainer = ancContainer.parent();
        }
        if (td) {
            td.css("background-color", params.color);
        }
    }
    this.changeSelectionColor("background-color", params.color);
};
/**清除格式支持只清除选区部分
 * 需要支持浮动面板的清除 eraserTip eraserAll eraserSelected eraserSection
 * **/
Kedit.prototype.eraser = function (params) {
    var range = this.getDomRange();
    var clearSpan = function (jqEle) {
        var tagName = jqEle[0].tagName;
        if (tagName === "SPAN") {
            jqEle.removeAttr("style");
            jqEle.attr("style", eConfig.defaultStyle);
            jqEle.children().each(function () {
                clearSpan($(this));
            });
        } else if (tagName === "TD") {
            jqEle.css({
                "border-width": "1px",
                "border-style": "dashed",
                "border-color": "rgb(175, 201, 222)",
                "background-color": "none"
            });
        }
    };
    var _this = this;
    this.confirmWin = $B.confirm({
        title: eConfig.label.eraserTip,
        message: eConfig.label.eraserTip,
        createToolsFn: function () {
            var wrap = this;
            var tool = $("<div class='k_confirm_buttons_wrap'></div>").appendTo(wrap);
            $("<button style='width:33.33333%' class='yes'><i  class='fa fa-eraser'>\u200B</i>" + eConfig.label.eraserAll + "</button>").appendTo(tool).click(function () {
                _this.confirmWin.close(true);
                var newFrag = document.createDocumentFragment();
                newFrag.appendChild(document.createElement("div"));
                var wrap = newFrag.firstChild;
                var html = _this.$input.html();
                _this.$input.children().remove();
                wrap.innerHTML = html;
                var htmlContent = [];
                var $wrap = $(wrap);
                $wrap.children().each(function () {
                    var $p = $(this).attr("style", "line-height: 21px; font-size: 14px;");
                    $p.children().each(function () {
                        clearSpan($(this));
                    });
                    htmlContent.push($p[0].outerHTML);
                });              
                //浮动文本 、图片
                _this.$inputWrap.children(".k_edit_float_panel").each(function () {
                    var tmp = $(this);
                    var $tag = tmp.clone();
                    var input = $tag.children(".k_editor_float_input").removeAttr("contenteditable");
                    input.children("div").each(function () {
                        var $p = $(this).attr("style", "line-height: 21px; font-size: 14px;");
                        $p.children().each(function () {
                            clearSpan($(this));
                        });
                    });
                    htmlContent.push($tag[0].outerHTML);
                    tmp.remove();
                });
                _this.setContent(htmlContent.join(""));
            });
            $("<button  style='width:33.33333%' class='no'><i  class='fa fa-eraser'>\u200B</i>" + eConfig.label.eraserSelected + "</button>").appendTo(tool).click(function () {
                _this.confirmWin.close(true);
                _this.setPaintTarget();
                _this.css(function (jqObj) {
                    clearSpan(jqObj);
                });
            });
            $("<button  style='width:33.33333%' class='yes'><i  class='fa fa-eraser'>\u200B</i>" + eConfig.label.eraserSection + "</button>").appendTo(tool).click(function () {
                _this.confirmWin.close(true);
                var startEl = _this.startPElement;
                var eachFn = function(){
                    clearSpan($(this));      
                };
                while(startEl.length > 0){//单个段落  
                    startEl.removeAttr("style").css(eConfig.pElementCss); 
                    startEl.children().each(eachFn);                            
                    if( startEl[0] === _this.endPElement[0]){
                        break;
                    }
                    startEl = startEl.next();
                }
            });
        }
    });
};
/**创建列表**/
Kedit.prototype._makeList = function (isOl, listStyle) {
    var insert = true;
    var listRootNode; // 列表根ol\ul对象
    if (this.range) {
        var listHtml;
        var container = this.range.commonAncestorContainer;
        var rangeInfo = this._getRangeInfo();
        var li, i, len, next;
        var isCrossPelement = this.isCrossPElement();
        if (!isCrossPelement) { //
            if (container.nodeType === 3) {
                container = $(container.parentNode);
            } else {
                container = $(container);
            }
            while (container.length > 0) {
                if (container.hasClass("_section_div_")) {
                    break;
                }
                var tagName = container[0].tagName;
                if (tagName === "TABLE" || tagName === "LI" || tagName === "OL" || tagName === "UL") {
                    insert = false;
                    if (tagName === "LI") {
                        listRootNode = container.parent();
                    } else if (tagName === "OL" || tagName === "UL") {
                        listRootNode = container;
                    }
                    break;
                }
                container = container.parent();
            }
            var lType = "";
            if(listStyle === "1"){
                lType = "decimal";
            }else if(listStyle === "i"){
                lType = "lower-roman";
            }else if(listStyle === "a"){
                lType = "lower-latin";
            }
            if (insert && listStyle !== "none") {                
                var html = container.html();
                container.children().remove();
                if (isOl) {
                    listHtml = "<ol type='" + listStyle + "' style='list-style-type:" + lType + ";list-style-position:inside;padding:0;margin:0;margin-block-start:0;padding-inline-start:0;-webkit-padding-start:0px;-webkit-margin-before:0;-webkit-margin-after:0;'><li id='" + getUUID() + "'>" + html + "</li></ol>";
                } else {
                    listHtml = "<ul style='list-style-position:inside;padding:0;margin:0;list-style-type:" + listStyle + ";padding-inline-start:0;-webkit-padding-start:0px;-webkit-margin-before:0;-webkit-margin-after:0;'><li id='" + getUUID() + "'>" + html + "</li></ul>";
                }
                container.append(listHtml);
                next = container.next();
                if (next.length === 0) {
                    this.insertPElement();
                    if (isOl) {
                        li = container.children("ol").children("li").last();
                    } else {
                        li = container.children("ul").children("li").last();
                    }
                }
                this.rebuildUserRange(rangeInfo);
            } else if (listRootNode) {
                var lastLi;
                if (isOl) { //有序列表
                    if (listStyle === "none") {
                        this._li2p(listRootNode);
                    } else {
                        listRootNode.attr("type", listStyle);
                        listRootNode.css("list-style-type", lType);
                        lastLi = listRootNode.children().last();
                    }
                } else { //符号列表
                    if (listStyle === "none") {
                        this._li2p(listRootNode);
                    } else {
                        listRootNode.css("list-style-type", listStyle);
                        lastLi = listRootNode.children().last();
                    }
                }
                this.rebuildUserRange(rangeInfo);
            }
        } else { //选择了多个段落
            var nodeName = container.nodeName;
            if (nodeName === "OL") {
                return;
            }
            if (nodeName === "UL") {
                $(container).children().each(function () {
                    $(this).css("list-style-type", listStyle);
                });
                return;
            }
            var htmlArray = [],
                lineHeightArray = [],
                id,
                firstPele,
                removeEles = []; //移除的p元素
            if (this.painTargets.length === 0) {
                this.setStartAndEndPElementByRange();
            }
            //按段落形成有序内容              
            this.foreachPTargets(function (p) {
                if (!firstPele) {
                    firstPele = p;
                } else {
                    removeEles.push(p);
                }
                htmlArray.push(p.html());
                lineHeightArray.push(p.css("line-height"));
                var firstChild = p.children().first();
                var tagName = firstChild[0].tagName;
                if (tagName === "TABLE" || tagName === "LI") {
                    htmlArray = [];
                    firstPele = undefined;
                    removeEles = undefined;
                    return false;
                }
            });
            if (firstPele) {
                var eleIdsArray = [];
                for (i = 0, len = removeEles.length; i < len; ++i) {
                    id = removeEles[i].attr("id");
                    removeEles[i].remove();
                    eleIdsArray.push(id);
                }
                firstPele.html('');
                if (isOl) {
                    listHtml = "<ol type='" + listStyle + "' style='list-style-type:" + lType + ";list-style-type:decimal;list-style-position:inside;padding:0;margin:0;padding-inline-start:0;-webkit-padding-start:0px;-webkit-margin-before:0;-webkit-margin-after:0;'></ol>";
                } else {
                    listHtml = "<ul style='list-style-position:inside;padding:0;margin:0;list-style-type:" + listStyle + ";padding-inline-start:0;-webkit-padding-start:0px;-webkit-margin-before:0;-webkit-margin-after:0;'></ul>";
                }
                var ol = $(listHtml).appendTo(firstPele);
                for (i = 0, len = htmlArray.length; i < len; ++i) {
                    if (i === 0) {
                        id = getUUID();
                    } else {
                        id = eleIdsArray[i - 1];
                    }
                    ol.append("<li style='line-height:" + lineHeightArray[i] + "' id='" + id + "'>" + htmlArray[i] + "</li>");
                }
                next = firstPele.next();
                if (next.length === 0) {
                    this.insertPElement();
                    if (isOl) {
                        li = firstPele.children("ol").children("li").last();
                    } else {
                        li = firstPele.children("ul").children("li").last();
                    }
                }
                this.rebuildUserRange(rangeInfo);
            }
        }
    }
};
/**li转p段落**/
Kedit.prototype._li2p = function (listRootNode) {
    var p = listRootNode.parent();
    var firstPContent,
        newpContent = [],
        newpIdArray = [];
    //var fisrtLiId ;
    listRootNode.children().each(function (i) {
        var li = $(this);
        if (i === 0) {
            firstPContent = li.html();
            //fisrtLiId = li.attr("id");
        } else {
            newpContent.push(li.html());
            newpIdArray.push(li.attr("id"));
        }
    });
    p.html(firstPContent);//.attr("id" , fisrtLiId)
    for (var i = 0, len = newpIdArray.length; i < len; ++i) {
        var _c = newpContent[i];
        var $p = $("<" + sectionTag + " id='" + newpIdArray[i] + "' class='_section_div_'>" + _c + "</" + sectionTag + ">");
        p = $p.insertAfter(p);
    }
    listRootNode.remove();
    this.moveToEnd(p);
};
/***有序列表***/
Kedit.prototype.orderList = function (params) {
    var listStyle = params["list-style-type"];
    this._makeList(true, listStyle);
    this.createTargetsByRange();//重新建立 选区数据
};
/**插入代码**/
Kedit.prototype.insertCode = function (params) {
    var code = params.code;
    var insertTag = this._getInsertP();
    var pre = $("<pre style='line-height:1.6em;background-color:#F5F5F5;border-radius: 3px;padding: 3px 5px;margin: 0 3px;font-weight:normal;font-size:14px;color:#666666;'></pre>");
    pre.html(code);
    var span = insertTag.children("span").first();
    this.moveToEnd(span);
    span.siblings().remove();
    span.html("");
    pre.appendTo(span);
    this._bindPreEvents(pre);
    var $next = insertTag.next();
    if ($next.length === 0) {
        $next = this.createPElement();
        $next.insertAfter(insertTag);
        this.moveToEnd($next);
    }
};
Kedit.prototype._bindPreEvents = function ($pre) {
    $pre.mouseup(function (e) {
        var self = $(this);
        var pEl = self.parent();
        while (pEl.length > 0) {
            if (pEl[0].tagName === "DIV") {
                break;
            }
            pEl = pEl.parent();
        }
        var me = self.data("edit");
        me.startPElement = pEl;
        me.endPElement = pEl;
        _getBody().trigger("mouseup");
        me.openTIPWindow({
            top: e.pageY,
            left: e.pageX,
            $pre: self
        }, function (body, prs) {
            if (!me["preTip"]) { //                           
                me["preTip"] = $("<div><p class='_resetSection' style='cursor:pointer;display:none;'><i style='padding-right:4px;' class='fa fa-resize-horizontal'></i>" + eConfig.label.resetSectionWidth + "</p>" +
                    "<p class='_modifySection' style='cursor:pointer;'><i style='padding-right:4px;' class='fa fa-exchange'></i>" + eConfig.label.setSectionWidth + "</p>" +
                    "<p class='_delete_imag' style='cursor:pointer;'><i class='fa fa-cancel' style='padding-right:4px;'></i>" + eConfig.label.deleteCode + "</p>" +
                    "<p class='_modifyCode' style='cursor:pointer;'><i class='fa fa-edit' style='padding-right:4px;'></i>" + eConfig.label.modifyCode + "</p>" +
                    "<p class='_modifymove' style='cursor:pointer;'><i class='fa fa-move' style='padding-right:4px;'></i>" + eConfig.label.move + "</p></div>");
                me["preTip"].children("p._modifySection").click(function () {
                    me.setSectionWidth();
                    me["preTip"].detach();
                    me["tipWindow"].hide();
                });
                me["preTip"].children("p._resetSection").click(function () {
                    me.resetSectionWidth();
                    me["preTip"].detach();
                    me["tipWindow"].hide();
                });
                me["preTip"].children("p._delete_imag").click(function () {
                    var tip = $(this).parent();
                    tip.parent().parent().hide();
                    var pre = tip.data("$pre");
                    var span = pre.parent();
                    //删除操作 做记录                        
                    me._putUndoDataByNodeEl(span);
                    pre.remove();
                    tip.removeData("$pre");
                    var txt = span.text();
                    if (txt === "" && txt !== "\u200B") {
                        span.text("\u200B");
                    }
                    me.moveToEnd(span);
                });
                me["preTip"].children("p._modifyCode").click(function () {
                    var tip = $(this).parent();
                    tip.parent().parent().hide();
                    var pre = tip.data("$pre");
                    tip.removeData("$pre");
                    me.openCodeWindow("insertCode", { undo: false, needRange: false, sourceTag: pre });
                });
                me["preTip"].children("p._modifymove").click(function () {
                    var tip = $(this).parent();
                    tip.parent().parent().hide();
                    var pre = tip.data("$pre");
                    var pEl = pre.parent();
                    while (pEl.length > 0) {
                        if (pEl[0].tagName === "DIV") {
                            break;
                        }
                        pEl = pEl.parent();
                    }
                    me._setMovingTargets([pEl], false);
                    //console.log("移动代码>>>>>>>>>>>>>>>>>>>>");
                });
            }
            var $_pre = prs["$pre"];
            if (me.startPElement.css("padding-left") !== "0px") {
                me["preTip"].children("p._resetSection").show();
            } else {
                me["preTip"].children("p._resetSection").hide();
            }
            me["preTip"].data("$pre", $_pre);
            body.append(me["preTip"]);
            if (pEl.parent().hasClass("k_editor_float_input")) {
                me["preTip"].children("p._modifymove").hide();
            } else {
                me["preTip"].children("p._modifymove").show();
            }
        });
        //console.log("mouse up  code pre >>>>>>>>>>>>>>>>>>>");                
        me._setMovingTargets([pEl], false, function () {
            me["tipWindow"].hide();
        });
        return false;
    }).mousedown(function () {
        var self = $(this);
        var me = self.data("edit");
        me._closeCxtMenuImd();
        stopDefaultctxMenu();
        return false;
    }).keydown(function () {
        return false;
    }).keyup(function () {
        return false;
    }).data("edit", this);
};
/**无序列表**/
Kedit.prototype.unorderList = function (params) {
    var listStyle = params["list-style-type"];
    this._makeList(false, listStyle);
    this.createTargetsByRange();//重新建立 选区数据
};
/**字体大小**/
Kedit.prototype.fontSize = function (params) {
    var css = {
        "font-size": params["font-size"]
    };
    this.css(css);
};
/**居中对齐**/
Kedit.prototype.alignCenter = function (params) {
    this.setStartAndEndPElementByRange();
    var _this = this;
    this.foreachPTargets(function (p) {
        p.css({
            "text-align": "center"
        });
    });
};
Kedit.prototype.alignLeft = function (params) {
    this.setStartAndEndPElementByRange();
    this.foreachPTargets(function (p) {
        p.css({
            "text-align": "left"
        });
    });
};
Kedit.prototype.alignRight = function (params) {
    this.setStartAndEndPElementByRange();
    this.foreachPTargets(function (p) {
        p.css({
            "text-align": "right"
        });
    });
};
/**取消链接**/
Kedit.prototype.unlink = function (params) {
    var range = this.range;
    var ancer = range.commonAncestorContainer;
    var aEle;
    if (ancer.nodeType === 3) {
        aEle = $(ancer.parentNode);
    } else {
        aEle = $(aEle);
    }
    if (aEle[0].nodeName === "A") {
        var html = aEle.text();
        var cpStyle = this._getCopyStyle(aEle);
        var parent = aEle.parent();
        aEle.remove();
        parent.html(html).css(cpStyle);
        //parent.removeAttr("contenteditable");
        this.createCrossRange(parent, parent);
    }
};
/**编辑链接**/
Kedit.prototype.editLink = function (params) {
    var range = this.range;
    var ancer = range.commonAncestorContainer;
    var aEle;
    if (ancer.nodeType === 3) {
        aEle = $(ancer.parentNode);
    } else {
        aEle = $(aEle);
    }
    if (aEle[0].nodeName === "A") {
        this.createCrossRange(aEle, aEle);
        this._openLinkWindow({
            wrap: aEle
        }, aEle.text());
    }
};
/**打开链接设置窗口
 * params = {nodeValue:,startOffset:,endOffset:,wrap}
 * **/
Kedit.prototype._openLinkWindow = function (params, txt) {
    var _this = this;
    this.openWindow({
        title: eConfig.label.updateLink,
        width: 400,
        height: 200,
        contentFn: function (body, params) {
            var $addr, $target;
            if (!_this["linkForm"]) {
                _this["linkForm"] = $(eConfig.linkForm);
                var validObj,
                    $name = _this["linkForm"].find("#_link_name");
                $addr = _this["linkForm"].find("#_addr_url"),
                    $target = _this["linkForm"].find("#_target_");
                _this["linkForm"].find("button").click(function () {
                    if (!validObj || validObj.valid()) {
                        _this.closeWindow();
                        var prs = _this["linkForm"].data("params");
                        _this["linkForm"].removeData("params");
                        var t = $target.prop("checked") ? '_blank' : '_self';
                        var addr = $addr.val();
                        if (addr.indexOf("http") < 0) {
                            addr = "http://" + addr;
                        }
                        if (prs.wrap[0].nodeName === "A") {
                            prs.wrap.attr({
                                target: t,
                                href: addr
                            }).text($name.val());
                        } else {
                            var a = '<a target="' + t + '" href="' + addr + '" id="' + getUUID() + '">';
                            var $a;
                            if (prs.mutilTags) {
                                console.log("跨元素选区》》》》》");
                                var aList = prs.wrap;
                                var aEle, firstEl, lastEl;
                                for (var i = 0, len = aList.length; i < len; ++i) {
                                    aEle = aList[i];
                                    aEle.html(a + aEle.text() + "</a>");
                                    $a = aEle.children();
                                    if (i === 0) {
                                        firstEl = $a;
                                    }
                                    if (i === len - 1) {
                                        lastEl = $a;
                                    }
                                    _this._bindAEleEvents($a);
                                }
                                _this.createCrossRange(firstEl, lastEl);
                            } else {
                                a = a + $name.val() + '</a>';
                                var spanHtmls = _this._text2spanWrap(prs.nodeValue, prs.startOffset, prs.endOffset, true);
                                var copyStyle = _this._getCopyStyle(prs.wrap);
                                if (spanHtmls !== "") {
                                    var spans = $(spanHtmls).insertAfter(prs.wrap);
                                    prs.wrap.remove();
                                    var taget;
                                    spans.each(function () {
                                        var $t = $(this);
                                        if ($t.hasClass("_wrap_target_node_")) {
                                            taget = $t;
                                            return false;
                                        }
                                    }).css(copyStyle);
                                    taget.html(a).removeClass("_wrap_target_node_");
                                    $a = taget.children();
                                } else {
                                    prs.wrap.html(a);
                                    $a = prs.wrap.children();
                                }
                                $a.css("text-decoration", "underline");
                                _this._getSpan().insertAfter($a.parent());
                                _this.createCrossRange($a, $a);
                                $a.css(copyStyle);
                                _this._bindAEleEvents($a);
                            }
                        }
                    }
                });
                //创建验证
                if ($B.Validate) {
                    validObj = new $B.Validate({
                        "_link_name": [{
                            rule: 'require'
                        }],
                        "_addr_url": [{
                            rule: 'require'
                        }, {
                            rule: 'url'
                        }]
                    }, _this["linkForm"]);
                }
            }
            _this["linkForm"].data("params", params);
            _this["linkForm"].find("#_link_name").val(txt);
            if (params.wrap[0].nodeName === "A") {
                $addr = _this["linkForm"].find("#_addr_url");
                $target = _this["linkForm"].find("#_target_");
                $addr.val(params.wrap.attr("href"));
                if (params.wrap.attr("target") === "_blank") {
                    $target.prop("checked", true);
                } else {
                    $target.prop("checked", false);
                }
            }
            body.append(_this["linkForm"]);
        }
    }, params);
};
/**
 * 插入超链接
 * ***/
Kedit.prototype.link = function (params) {
    var range = this.range;
    var tmpArray = [];
    var i, len;
    var ancer = range.commonAncestorContainer;
    var prs = {
        nodeValue: undefined,
        startOffset: range.startOffset,
        endOffset: range.endOffset,
        wrap: undefined
    };
    if (ancer.nodeType !== 3) {
        this.setPaintTarget();
        var tgs = this.painTargets;
        var tg;
        for (i = 0, len = tgs.length; i < len; ++i) {
            tg = tgs[i];
            tmpArray.push(tg.text());
        }
        prs.nodeValue = tmpArray.join("");
        prs.wrap = tgs;
        prs.mutilTags = true;//跨标签设置超链接
        //console.log(eConfig.label.nosuport + tmpArray.join(""));
        //return;
    } else {
        var parent = $(ancer.parentNode);
        prs.nodeValue = ancer.nodeValue;
        prs.wrap = parent;
        for (i = 0, len = prs.nodeValue.length; i < len; ++i) {
            if (i >= prs.startOffset && i < prs.endOffset) {
                tmpArray.push(prs.nodeValue[i]);
            } else if (i >= prs.endOffset) {
                break;
            }
        }
    }
    var txt = tmpArray.join("");
    this._openLinkWindow(prs, txt);
};
/**绑定a标签事件**/
Kedit.prototype._bindAEleEvents = function ($a) {
    $a.mouseup(function (e) {
        var aEle = $(this);
        var me = aEle.data("selft");
        var addr = aEle.attr("href");
        var lastEl, firstEl, $el;
        var txtArray = [];
        var $aArray = [];
        var span = aEle.parent();
        var prev = span.prev();
        while (prev.length > 0) {
            $el = prev.children("a");
            if ($el.length === 0) {
                break;
            }
            if (addr !== $el.attr("href")) {
                break;
            }
            txtArray.unshift($el.text());
            $aArray.unshift($el);
            prev = prev.prev();
        }
        txtArray.push(aEle.text());
        $aArray.push(aEle);

        var next = span.next();
        while (next.length > 0) {
            $el = next.children("a");
            if ($el.length === 0) {
                break;
            }
            if (addr !== $el.attr("href")) {
                break;
            }
            txtArray.push($el.text());
            $aArray.push($el);
            next = next.next();
        }
        //var flag = aEle.attr("flag");

        me["_clickLinkTag"] = $aArray;
        firstEl = $aArray[0];
        lastEl = $aArray[$aArray.length - 1];

        var txt = txtArray.join("");
        me.openTIPWindow({
            top: e.pageY,
            left: e.pageX
        }, function (body) {
            if (!me["linkTip"]) {
                me["linkTip"] = $("<div>" + eConfig.label.visit + "：<a target='blank' href='" + addr + "'>" + txt + "</a><br/><p style='cursor:pointer;'>" + eConfig.label.deleteLink + "</p></div>");
                me["linkTip"].children("p").click(function () {
                    var $t = $(this);
                    var eles = me._clickLinkTag;
                    if (eles.length > 0) {//加入撤销记录
                        me._putUndoDataByNodeEl(eles[0]);
                    }
                    var ele, parent;
                    for (var j = 0, jlen = eles.length; j < jlen; ++j) {
                        ele = eles[j];
                        parent = ele.parent();
                        if (parent.contents().length === 1) {
                            parent.html("\u200B");
                        }
                        ele.remove();
                    }
                    me._clickLinkTag = undefined;
                    me.moveToEnd(parent);
                    $t.parent().parent().parent().hide();
                    if (me.opts.onDeleted) {
                        me.opts.onDeleted.call(ele, ele.attr("href"));
                    }
                });
            }
            me["linkTip"].children("a").attr("href", addr).text(txt);
            body.append(me["linkTip"]);
        });
        me.createCrossRange(firstEl, lastEl);
    }).data("selft", this);
};
/**
 * 插入表情
 * **/
Kedit.prototype.emotion = function (prs) {
    var insertSpan = this._getInsertSpan();
    if (insertSpan) {
        var base64, height, width;
        if (prs.isIcon) {
            base64 = prs.icon;
            height = prs.height;
            width = prs.width;
        } else {
            height = 19;
            width = 19;
            base64 = window.kemConfig[prs.gif];
        }
        var gif = $("<span style='" + eConfig.defaultStyle + "' id='" + getUUID() + "'>\u200B<img  class='_emotion_' id='" + getUUID() + "' src='" + base64 + "' style='width:" + width + "px;height:" + height + "px;margin-left:1px ;margin-right:1px;'/>\u200B</span>");
        gif.css("background", "none");
        gif.insertAfter(insertSpan);
        var span = this._getSpan().insertAfter(gif);
        var prevSpan = gif.prev();
        var copyStyle;
        if (prevSpan.length > 0) {
            copyStyle = this._getCopyStyle(prevSpan);
            span.css(copyStyle);
        } else {
            copyStyle = span.parent().css("background-color");
            span.css("background-color", copyStyle);
        }
        this._bindImageEvents(gif.children("img"));
        this.moveToEnd(span);
    }
};
/**插入图片
 * {"undo":false,"needRange":false,"url":"20180712095010.png","width":"100","height":"100","position":"center"}**/
Kedit.prototype.picture = function (params) {
    var url = params.url,
        width = params.width,
        height = params.height,
        position = params.position;
    var _this = this;
    var margin = {
        "margin-top": params.top + "px",
        "margin-right": params.right + "px",
        "margin-bottom": params.bottom + "px",
        "margin-left": params.left + "px"
    };
    if (this.clickActivedObject && this.clickActivedObject.className === "table") {
        var clickTd = this.clickActivedObject.clickTd;
        if (!clickTd && this.range) {
            var acontainer = this.range.commonAncestorContainer;
            if (acontainer.nodeType === 3) {
                acontainer = $(acontainer.parentNode);
            } else {
                acontainer = $(acontainer);
            }
            while (acontainer.length > 0) {
                if (acontainer[0].tagName === "TD") {
                    clickTd = acontainer;
                    break;
                }
                acontainer = acontainer.parent();
            }
        }
        if (clickTd) {
            var $img = this._createImage(url, width, height).css(margin);            
            if (position !== 'inner') {
                $img.prependTo(clickTd);
                clickTd.css("text-align", position);
                if(params.isAuto){
                    $img.width("100%");
                    $img.height("auto");
                }
                if(params.link){
                    if(params.link === ""){
                        $img.removeAttr("link");
                    }else{
                        $img.attr("link",params.link);
                    }        
                }
            } else {//行内插入
                this.lineInnerImage(url, width, height, true);
            }
            this.clickActivedObject.reSize();
            this.clickActivedObject.reSize(true);//设置大小 
        }
        return;
    }
    var targetP;
    if (position !== "inner") {
        this._getRangeSections(function (p) {
            targetP = p;
        });
        if (targetP.children("ol").length > 0 || targetP.children("ul").length > 0) {
            targetP = this.createPElement().insertAfter(targetP);
        }
    }
    var $newImg;
    if (position === "center") {
        var txt = targetP.text();
        var insertTag;
        if (txt === "" || txt === "\u200B") {
            insertTag = targetP;
        } else {
            var $p = this.createPElement();
            insertTag = $p.insertAfter(targetP);
        }
        insertTag.css("text-align", "center");
        $newImg = this._createImage(url, width, height).css(margin).appendTo(insertTag);
    } else if (position === "inner") {//行内图片
        this.lineInnerImage(url, width, height);
        return;
    } else {
        insertTag = targetP;
        targetP.addClass("clearfix");
        $newImg = this._createImage(url, width, height).css(margin).css("float", position).appendTo(insertTag);
    }
    var $span = this._getSpan().insertBefore($newImg);
    this._getSpan().insertAfter($newImg);
    if (position !== "inner") {
        $newImg.css("text-align", position);
    }
    var nextPelement = insertTag.next();
    if (nextPelement.length === 0) {
        nextPelement = this.insertPElement();
    }
    if(params.isAuto){
        $newImg.width("100%");
        $newImg.height("auto");
    }
    if(params.link){
        if(params.link === ""){
            $newImg.removeAttr("link");
        }else{
            $newImg.attr("link",params.link);
        }        
    }
    setTimeout(function () {
        if (position === "center") {
            _this.moveToEnd(nextPelement);
        } else {
            _this.moveToEnd($span);
        }
    }, 100);
    return $newImg;
};
/**插入行内图片***/
Kedit.prototype.lineInnerImage = function (url, width, height, isTd) {
    var $newImg = this._createImage(url, width, height).addClass("k_inner_image").css({ "margin-left": "1px", "margin-right": "1px" });
    var insertSpan, pEl, gifSPAN, nextspan, _this = this;
    insertSpan = this._getInsertSpan();
    pEl = insertSpan.parent();
    while (pEl.length > 0) {
        if (pEl.hasClass("_section_div_")) {
            break;
        }
        pEl = pEl.parent();
    }
    gifSPAN = this._getSpan();
    gifSPAN.append($newImg);
    var emptTxt = this._createEmptyTextNode();
    gifSPAN.append($newImg);
    gifSPAN.append(emptTxt);
    gifSPAN.insertAfter(insertSpan);
    nextspan = this._getSpan().insertAfter(gifSPAN);
    $newImg.css("border", "1px solid #F0F0F0");
    if (!isTd) {
        if (pEl.next().length === 0) {
            this.createPElement().insertAfter(pEl);
        }
    }
    setTimeout(function () {
        //图片居中修饰
        var top = (gifSPAN.height() - $newImg.height()) / 2;
        $newImg.css({
            'position': 'relative',
            'top': top + "px"
        });
        _this.moveToEnd(nextspan);
    }, 100);
};
/**
 * 更新图片大小、边距
 * **/
Kedit.prototype.updateImage = function (params) {
    var $img = params["$img"];
    var css = {
        "margin-top": params["top"] + "px",
        "margin-left": params["left"] + "px",
        "margin-bottom": params["bottom"] + "px",
        "margin-right": params["right"] + "px",
        "width": params["width"],
        "height": params["height"]
    };
    $img.css(css);
    if(params.isAuto){
        $img.width("100%");
        $img.height("auto");
    }
    if(params.link){
        if(params.link === ""){
            $img.removeAttr("link");
        }else{
            $img.attr("link",params.link);
        }        
    }
    var $p = $img.parent();
    var align = params["position"];
    var style = $img.attr("style");
    var go = false;
    if (align === "center") {
        go = true;
        style = style.replace(/float:\s*(left|right)/g, "");
        var txt = $p.text().replace(/\u200B/g, "");
        if (txt === "") {
            $p.css("text-align", "center").removeClass("clearfix");
        } else {
            var newP = this.createPElement().insertAfter($p).css("text-align", "center");
            $img.detach().appendTo(newP);
            this._getSpan().insertAfter(newP);
            $p.removeClass("clearfix");
            if (newP.next("._section_div_").length === 0) {
                this.createPElement().insertAfter(newP);
            }
            this.moveToEnd(newP);
        }
    } else if (align !== "inner") {
        $p.css("text-align", "left").addClass("clearfix");
        var v;
        if (align === "left") {
            v = "float:left";
            style = style.replace(/(text-align|float):\s*(center|right)/g, v);
        } else {
            v = "float:right";
            style = style.replace(/(text-align|float):\s*(center|left)/g, v);
        }
        go = true;
    }
    $img.attr("style", style);
    if (go) {
        $img.css("text-align", align);
    }
};
Kedit.prototype._createImage = function (url, width, height) {
    var $img = $("<img id='" + getUUID() + "' tabindex='0' src='" + url + "' style='width:" + width + "px;height:" + height + "px' />");
    var _this = this;
    setTimeout(function () {
        _this._bindImageEvents($img);
    }, 10);
    return $img;
};
Kedit.prototype._bindImageEvents = function ($img) {
    var _this = this;
    //$img[0].ondragstart = function(){return false};
    $img.keyup(function (e) {
        if (e.which === 46) {
            //console.log("delete img....");
        }
    }).keydown(function () {
        //console.log("key down >>>>>>>>>>>>>>");
    }).mousedown(function (e) {
        //console.log("image events >>>>> ");
        var box = $(this);
        var me = box.data("edit");
        var isEmotion = box.hasClass("_emotion_");
        me._closeCxtMenuImd();
        if (e.which === 3) {
            stopDefaultctxMenu();
            if (!isEmotion) {
                if (_this["resizeBox"]) {
                    if (_this["resizeBox"].target && _this["resizeBox"].target[0] === box[0]) {
                        _this["resizeBox"].unbind();
                    }
                }
            }
        } else {
            if (me["tipWindow"]) {
                me["tipWindow"].hide();
            }
            if (!_this["resizeBox"] && !isEmotion) {
                _this._createResizeBox(box);
            }
            if (_this["resizeBox"] && !isEmotion) {
                _this["resizeBox"].bind(box);
            }
        }
        e.preventDefault();
        return false;
    }).mouseup(function (e) {
        _this.clickActivedDomObject = $(this);
        _this.clickActivedDomObject.addClass("k_edit_actived_object");
        var self = $(this);
        var isEmotion = self.hasClass("_emotion_");
        var isInnerImg = self.hasClass("k_inner_image");
        var me = self.data("edit");
        if (e.which === 3) {
            me.openTIPWindow({
                top: e.pageY,
                left: e.pageX,
                img: self
            }, function (body, prs) {
                if (!me["imgTip"]) { //
                    me["imgTip"] = $("<div><p class='_delete_imag' style='cursor:pointer;'><i class='fa fa-cancel' style='padding-right:4px;'></i>" + eConfig.label.deleteImg + "</p>" +
                        "<p class='_setborder_imag' style='cursor:pointer;'><i class='fa fa-check-empty' style='padding-right:4px;'></i>" + eConfig.label.setborder + "</p>" +
                        "<p class='_seting_imag' style='cursor:pointer;'><i class='fa fa-edit' style='padding-right:4px;'></i>" + eConfig.label.modify + "</p>" +
                        "<p class='_section_imag' style='cursor:pointer;'><i style='padding-right:4px;' class='fa fa-exchange'></i>" + eConfig.label.setSectionWidth + "</p>" +
                        "<p class='_resection_imag' style='cursor:pointer;display:none;'><i style='padding-right:4px;' class='fa fa-resize-horizontal'></i>" + eConfig.label.resetSectionWidth + "</p>" +
                        "<p class='_move_imag' style='cursor:pointer;'><i class='fa fa-move' style='padding-right:4px;'></i>" + eConfig.label.move +
                        "<p class='_flow_imag' style='cursor:pointer;display:none;'><i class='fa fa-share-2' style='padding-right:4px'></i>" + eConfig.label.editFlow + "</div>"
                    );
                    me["imgTip"].children("p._delete_imag").click(function () {
                        if (me.movingAcn) {
                            me.movingAcn.hide();
                        }
                        var tip = $(this).parent();
                        tip.parent().parent().hide();
                        var $img = tip.data("image");
                        //delete me.FLOW_CACHE[$img.attr("id")];
                        var $p = $img.parent();
                        while ($p.length > 0) {
                            if ($p.hasClass("_section_div_")) {
                                break;
                            }
                            $p = $p.parent();
                        }
                        //删除操作 做记录                        
                        me._putUndoDataByNodeEl($p);
                        var imgWrap = $img.parent();
                        if (imgWrap.hasClass("._k_edit_img_wrap")) {
                            imgWrap.remove();
                        }
                        tip.removeData("image");
                        if ($p.contents().length === 0) {
                            $p.append('<span style="' + eConfig.defaultStyle + '" id="' + getUUID() + '">\u200B</span>');
                        }
                        $p.css("text-align", "left");
                        me.moveToEnd($p);
                        if ($p.children("img").length === 0) {
                            $p.removeClass("clearfix");
                        }
                        $img.remove();
                        if (me.opts.onDeleted) {
                            me.opts.onDeleted.call($img, $img.attr("src"));
                        }
                    });
                    me["imgTip"].children("p._seting_imag").click(function () {
                        var tip = $(this).parent();
                        tip.parent().parent().hide();
                        var img = tip.data("image");
                        var style = me._getCopyStyle(img);
                        var _prs = $.extend({
                            "undo": false,
                            "needRange": false,
                            "width": img.outerWidth() + "",
                            "height": img.outerHeight() + "",
                            "$img": img
                        }, style);
                        me.openInsertImageWindow("updateImage", _prs);
                    });
                    //_resection_imag
                    me["imgTip"].children("p._section_imag").click(function () {
                        var tip = $(this).parent();
                        tip.parent().parent().hide();
                        var $img = tip.data("image");
                        var $p = $img.parent();
                        while ($p.length > 0) {
                            if ($p.hasClass("_section_div_")) {
                                break;
                            }
                            $p = $p.parent();
                        }
                        _this.startPElement = $p;
                        _this.endPElement = $p;
                        _this.setSectionWidth();
                    });
                    //_resection_imag
                    me["imgTip"].children("p._resection_imag").click(function () {
                        var tip = $(this).parent();
                        tip.parent().parent().hide();
                        var $img = tip.data("image");
                        var $p = $img.parent();
                        while ($p.length > 0) {
                            if ($p.hasClass("_section_div_")) {
                                break;
                            }
                            $p = $p.parent();
                        }
                        _this.startPElement = $p;
                        _this.endPElement = $p;
                        _this.resetSectionWidth();
                    });
                    me["imgTip"].children("p._move_imag").click(function () {
                        var tip = $(this).parent();
                        var $img = tip.data("image");
                        me._setMovingTargets($img, true);
                        tip.parent().parent().hide();
                    });
                    //边框设置
                    me["imgTip"].children("p._setborder_imag").click(function () {
                        var tip = $(this).parent();
                        tip.parent().parent().hide();
                        me.openBorderForm(me["imgTip"].data("image"));
                    });
                    //流程编辑
                    me["imgTip"].children("p._flow_imag").click(function () {
                        var flowImg = me["imgTip"].data("image");
                        var imgId = flowImg.attr("id");
                        var flowData = me.FLOW_CACHE[imgId];
                        me.flowOpen(flowData, flowImg);
                    });
                }
                var $ss = me["imgTip"].children("p._seting_imag");
                var $s1 = me["imgTip"].children("p._section_imag");
                var $s2 = me["imgTip"].children("p._move_imag");
                var $s3 = me["imgTip"].children("p._setborder_imag");
                var $s4 = me["imgTip"].children("p._resection_imag");
                var $s5 = me["imgTip"].children("p._flow_imag");
                if (isEmotion || isInnerImg) {
                    $ss.hide();
                    $s1.hide();
                    $s2.hide();
                    if (isEmotion) {
                        $s3.hide();
                    } else {
                        $s3.show();
                    }
                    $s4.hide();
                } else {
                    $ss.show();
                    $s1.show();
                    $s2.show();
                    $s3.show();
                }
                var $img = prs["img"];
                if ($img.hasClass("k_editor_flow_img")) {
                    var id = $img.attr("id");
                    //查询sessionStorage
                    if (me.FLOW_CACHE[id]) {
                        $s5.show();
                    } else {
                        $s5.hide();
                    }
                } else {
                    $s5.hide();
                }
                me["imgTip"].data("image", $img);
                if (!isEmotion && !isInnerImg) {
                    var tmpSe = me["imgTip"].children("p._resection_imag");
                    var pElSe = $img.parent();
                    while (pElSe.length > 0) {
                        if (pElSe[0].tagName === "DIV") {
                            break;
                        }
                        pElSe = pElSe.parent();
                    }
                    if (pElSe.css("margin-left") !== "0px") {
                        tmpSe.show();
                    } else {
                        tmpSe.hide();
                    }
                }
                body.append(me["imgTip"]);
            });
        } else {
            if (!isEmotion && !isInnerImg) {
                me._setMovingTargets(self, true);
            }
        }
        return false;
    }).data("edit", this);
};
/**
* 上传文件
* ***/
Kedit.prototype.upload = function (params) {
    var range = this.range;
    if (range) {
        var linkName = params["linkName"];
        var addr = params["url"];
        var a = $('<a flag="1" target="_blank" href="' + addr + '" id="' + getUUID() + '">' + linkName + '</a>');
        var endContainer = range.endContainer;
        var endOffset = range.endOffset;
        var nodeValue = endContainer.nodeValue;
        var wrap = $(endContainer.parentNode);
        var copyStyle = this._getCopyStyle(wrap);
        var aEleStyle = $.extend({}, copyStyle);
        aEleStyle["text-decoration"] = "underline";
        a.css(aEleStyle);
        if (nodeValue !== "" && nodeValue !== "\u200B") {
            var tags = $(this._text2spanWrap(nodeValue, 0, endOffset, false));
            tags.css(copyStyle);
            if (wrap[0].tagName === "TD") {
                wrap.html("");
                tags.appendTo(wrap);
            } else {
                tags.insertAfter(wrap);
                wrap.remove();
            }
            var target;
            tags.each(function () {
                var $t = $(this);
                if ($t.hasClass("_wrap_target_node_")) {
                    target = $t.removeClass("_wrap_target_node_");
                }
            });
            a.insertAfter(target);
            this.moveToEnd(this._getSpan().insertAfter(a).css(copyStyle));
        } else {
            wrap.html("");
            if (wrap[0].tagName === "TD") {
                wrap.append(a);
                var newSpan = this._getSpan().css(copyStyle).appendTo(wrap);
                this.moveToEnd(newSpan);
            } else {
                a.appendTo(wrap);
                if (wrap.prev().length === 0) {
                    this._getSpan().css(copyStyle).insertBefore(wrap);
                }
                this.moveToEnd(this._getSpan().css(copyStyle).insertAfter(wrap));
            }
        }
        this._bindAEleEvents(a);
        return a;
    }
};
/**
* 分割线
* **/
Kedit.prototype.split = function (params) {
    var section = this.getRangeSection();
    if (section) {
        var target;
        if (this.isEmptySectionFn(section)) {
            target = section;
        } else {
            target = this.createPElement();
            target.insertAfter(section);
        }
        target.css(eConfig.lineCss).addClass("_exclude_ k_split_line").attr({
            "line": "true",
            "contenteditable": "false"
        });
        var next = target.next();
        if (next.length === 0) {
            next = this.createPElement();
            next.insertAfter(target);
        }
        // console.log("split move ----");
        this.moveToEnd(next);
        this._bindSplitLineEvent(target);
    }
};
Kedit.prototype._bindSplitLineEvent = function ($line) {
    var _this = this;
    $line.on({
        "mousedown": function (e) {
            if (e.which === 3) {
                stopDefaultctxMenu();
            }
            return false;
        },
        "mouseup": function (e) {
            var $t = $(this);
            var _this = $t.data("_this");
            _this.showSplitTip(e, $t);
            return false;
        }
    }).data("_this", _this);
};
Kedit.prototype.showSplitTip = function (e, self) {
    var _this = this;
    _this.openTIPWindow({
        top: e.pageY,
        left: e.pageX,
        self: self
    }, function (body, prs) {
        if (!_this["splitmenu"]) {
            _this["splitmenu"] = $("<div><p class='_delete_split' style='cursor:pointer;'>" + eConfig.label.deleteSplit + "</p><p class='_seting_split' style='cursor:pointer;'>" + eConfig.label.modify + "</p></div>");
            _this["splitmenu"].children("._delete_split").click(function () {
                var $t = $(this).parent();
                var $tag = $t.data("split");
                //删除操作 做记录                        
                _this._putUndoDataByNodeEl($tag);
                var activedSection = $tag.next();
                if (activedSection.length === 0) {
                    activedSection = $tag.prev();
                }
                _this.closeTIPWindow();
                $tag.remove();
                _this.moveToEnd(activedSection);
            });
            _this["splitmenu"].children("._seting_split").click(function () {
                var $t = $(this).parent();
                var $tag = $t.data("split");
                _this.closeTIPWindow();
                _this.openSplitWindow({
                    "tag": $tag
                });
            });
        }
        _this["splitmenu"].data("split", prs["self"]);
        body.append(_this["splitmenu"]);
    });
};
Kedit.prototype.openSplitWindow = function (params) {
    var _this = this;
    this.openWindow({
        title: eConfig.label.splitLineUpdate,
        width: 300,
        height: 200,
        notIfr: true,
        contentFn: function (body, prs) {
            if (!_this["splitForm"]) {
                _this["splitForm"] = $(eConfig.splitForm);
                _this["splitForm"].find("#_line_size").on("change", function () {
                    var size = $(this).val();
                    var params = _this["splitForm"].data("params");
                    var tag = params["tag"];
                    tag.css("border-bottom-width", size);
                });
                _this["splitForm"].find("#_line_style").on("change", function () {
                    var style = $(this).val();
                    var params = _this["splitForm"].data("params");
                    var tag = params["tag"];
                    tag.css("border-bottom-style", style);
                });
                _this["splitForm"].find("#_line_top").on("input", function () {
                    var v = $(this).val();
                    if (v !== "") {
                        var params = _this["splitForm"].data("params");
                        var tag = params["tag"];
                        tag.css("margin-top", parseInt(v) + 4 + "px");
                    }
                });
                _this["splitForm"].find("#_line_bottom").on("input", function () {
                    var v = $(this).val();
                    if (v !== "") {
                        var params = _this["splitForm"].data("params");
                        var tag = params["tag"];
                        tag.css("margin-bottom", parseInt(v) + 4 + "px");
                    }
                });
                _this._createWindowColorPicker();
            }
            var _color = params["tag"].css("border-bottom-color").toHexColor();
            var _size = params["tag"].css("border-bottom-width");
            var _style = params["tag"].css("border-bottom-style");
            var mTop = parseInt(params["tag"].css("margin-top").replace("px", "") - 4);
            var mBottom = parseInt(params["tag"].css("margin-bottom").replace("px", "") - 4);
            _this["splitForm"].find("#_line_top").val(mTop);
            _this["splitForm"].find("#_line_bottom").val(mBottom);
            var loopFn = function () {
                var $t = $(this);
                if ($t.val() === _size) {
                    $t.prop("selected", true);
                } else {
                    $t.prop("selected", false);
                }
            };
            _this["splitForm"].find("#_line_size").children().each(loopFn);
            _this["splitForm"].find("#_line_style").children().each(loopFn);
            var $color = _this["splitForm"].find("#_line_color_").val(_color).css("background-color", _color);
            _this["splitForm"].data("params", prs);
            body.append(_this["splitForm"]);
            var ifrPos = _this[_this.windowName + "_iframe"].offset();
            var picker = _this[_this.windowName].data("colorPicker");
            picker.unbindTarget();
            picker.opts.positionFix = {
                left: ifrPos.left + 4,
                top: ifrPos.top + 4
            };
            picker.setTarget($color).setValue(_color);
            picker.opts.change = function (hex, opacity) {//注册颜色变化函数
                params["tag"].css("border-bottom-color", hex);
            };
        }
    }, params, this.setWindowColorPickerPosition);
    this.setWindowColorPickerPosition();
};
/***
 * 插入地图，走插入图片逻辑
 * ***/
Kedit.prototype.insertMap = function (imgData, width, height) {
    var src = imgData;
    if (typeof this.opts.onInsertMap === "function") {
        src = this.opts.onInsertMap(imgData);
    }
    var prs = {
        "undo": false,
        "needRange": false,
        "url": src,
        "width": width,
        "height": height,
        "position": "left"
    };
    var img = this.picture(prs);
    img.addClass("k_editor_map_img");
};
/**预览**/
Kedit.prototype.preview = function (params) {
    var page = eConfig.preview;
    window["curEditor"] = this;
    window["_isMobile_e"] = this.opts.mobile;
    if (window["_isMobile_e"]) {
        window["_mobile_w"] = this.$fixInput.outerWidth();
        window["_mobile_h"] = this.$fixInput.outerHeight();
    }
    $B.window({
        title: eConfig.tools.preview,
        full: true,
        dataType: 'iframe',
        url: page
    });
};
Kedit.prototype.fullprint = function (prs, button) {
    //console.log("full print >>>>>>");
    var srcWrap;
    var rangeInfo = this._getRangeInfo();
    if (this.jqObj.data("isFull")) {
        this.jqObj.removeData("isFull");
        srcWrap = this.jqObj.data("srcWrap");
        this.jqObj = this.jqObj.detach();
        srcWrap.append(this.jqObj);
        this.jqObj.removeData("srcWrap");
        if (this.fullWrap) {
            this.fullWrap.remove();
            this.fullWrap = undefined;
        }
        button.children("i").removeClass("fa-resize-small").addClass("fa-resize-full");
        this.jqObj.height(this.jqObj.data("src_height"));
        this.jqObj.width(this.jqObj.data("src_width"));
        if (this.opts.mobile) {
            this.$inputWrap.css("border-left-width", this.jqObj.data("src_border_l"));
            this.$inputWrap.css("border-right-width", this.jqObj.data("src_border_r"));
        }
    } else {
        var lwidth;
        if (this.opts.mobile) { //处理浮动文本的 位置问题
            lwidth = this.$inputWrap.css("border-left-width");
            var rwidth = this.$inputWrap.css("border-right-width");
            this.jqObj.data("src_border_l", lwidth);
            this.jqObj.data("src_border_r", rwidth);
            console.log(" lwidth =" + lwidth);
        }

        this.fullWrap = $("<div class='k_box_size' style='position: absolute; z-index:666666; top: 0px; left: 0px; width: 100%; height: 100%;'></div>");
        var $b = _getBody();
        this.fullWrap.appendTo($b);
        srcWrap = this.jqObj.parent();
        this.jqObj.data("isFull", true);
        this.jqObj.data("srcWrap", srcWrap);
        if (!this.jqObj.data("src_height")) {
            this.jqObj.data("src_height", this.jqObj.height());
        }
        if (!this.jqObj.data("src_width")) {
            this.jqObj.data("src_width", this.jqObj.width());
        }
        this.jqObj = this.jqObj.detach();
        this.fullWrap.append(this.jqObj);
        this.jqObj.outerHeight($b.height());
        this.jqObj.outerWidth($b.width());
        button.children("i").removeClass("fa-resize-full").addClass("fa-resize-small");
        if (this.opts.mobile) {
            var newBorderWidth = this.$fixInput.offset().left;
            this.$inputWrap.css("border-left-width", newBorderWidth + "px");
            var scrlWidth = $B.getScrollWidth() + 17;
            this.$inputWrap.css("border-right-width", ($b.width() - newBorderWidth - this.$fixInput.width() - scrlWidth) + "px");
        }
    }
    var _h = this.$inputWrap.siblings(".k_edit_tools_wrap").outerHeight() + 4;
    this.$inputWrap.css("border-top-width", _h);
    this.rebuildUserRange(rangeInfo);
};
Kedit.prototype.showVersion = function () {
    $B.message({ title: eConfig.label.version, height: 150, message: "<span style='line-height:1.5em'>version：" + VERVar + "</span><br/><span style='line-height:1.5em'>site：" + VERSite + "</span><br/><span style='line-height:1.5em'>release：" + VERDate + "</span>" });
};
/**
 * 使用帮助
 * ****/
Kedit.prototype.help = function () {
    var body = _getBody();
    var w = body.width() - 300;
    var h = body.height() - 100;
    $B.window({
        dataType: 'html',
        title: eConfig.label.help,
        width: w,
        height: h,
        url: 'help.html',
        onClosed: function () {
            clearInterval(window["_helperScrollChecking"]);
        }
    });
};
/***
 * 移动设备模拟
 * ***/
Kedit.prototype.mobile = function (params) {
    var _this = this;
    var size = params.phonesize.split("*");
    var width = parseInt(size[0]);
    var height = parseInt(size[1]);
    var floats;
    if (this.$inputWrap) {
        floats = this.$inputWrap.children(".k_edit_float_panel").hide();
    }
    this.$fixInput.parent().css({
        "border-left": "none",
        "border-right": "none"
    });
    this.$fixInput.css({
        "border-top": "20px solid #171717",
        "margin": "0 auto",
        "width": width,
        "min-height": height + "px"
    });
    var wrap = _this.$fixInput.parent();
    var marginRight = parseInt(_this.$fixInput.css("margin-left").replace("px", ""));
    var borderl = marginRight + "px solid rgb(242,242,242)";
    var scrlWidth = $B.getScrollWidth();
    var borderR = (marginRight - scrlWidth) + "px solid rgb(242,242,242)";
    wrap.css({
        "border-left": borderl,
        "border-right": borderR,
        "background": "rgb(242,242,242)"
    });
    if (floats) {
        floats.show();
    }
};
function initCodeEditor(window, document) {
    if (window["_codeCssObject_"]) {
        window["_codeCssObject_"].setTartets(window, document);
        return;
    }
    var code = new CodeCss(window, document);
    window["_codeCssObject_"] = code;
}

/***
 * 代码修饰类封装
 * ****/
function CodeCss(window, document) {
    $B.extend(this, CodeCss); //继承父类 
    this.range = undefined;
    this.setTartets(window, document);
}
CodeCss.prototype = {
    setTartets: function (window, document) {
        this.window = window;
        this.document = document;
        var body = $(document.body);   
        this.$inputWrap = body.find("#input_txt");            
        this.$input = this.$inputWrap.children("#k_code_input");
        this.$tool = body.find("#toolbar");
        this.head = $(document).find("head");
        this.bindEvnets();
        this.clearBg = true;
    },
    removeTargets: function () {
        try {
            this.$inputWrap.remove();
            this.$tool.remove();
            this.$inputWrap = undefined;
            this.$tool = undefined;
        } catch (ex) {
        }
    },
    /***
     * 清理背景色
     * ***/
    clearBackground: function (el) {
        el.css("background", "none");
        var color = el.css("color");
        if($B.isContrastYIQ(color) === "light"){//变深色
            var dcolor = $B.lightenDarkenColor(color.toHexColor() ,-45); //调用核心方法处理浅色
            el.css("color", dcolor);
        }
        var _this = this;
        el.children().each(function () {
            _this.clearBackground($(this));
        });
    },
    /***
     * 替换i标签
     * ***/
    replaceIelement: function (html) {
        html = html.replace(/(<\/i>)/gi, "</span>");
        html = html.replace(/(<\/em>)/gi, "</span>");
        return html;
    },
    /***
     * 绑定事件
     * **/
    bindEvnets: function () {
        var _this = this;
        this.$tool.children(".font_css").focus(function () {
            _this.rebuildUserRange();
        }).click(function () {
            var $t = $(this);
            var id = $t.attr("id");
            var css;
            var sColor;
            if (id === "bold") {
                css = { "font-weight": "bold" };
            } else if (id === "normal") {
                css = { "font-weight": "normal" };
            } else {
                sColor = $t.attr("color");
                css = { "color": sColor };
            }
            if (sColor) {
                _this.changeSelectionColor("color", sColor);
            }
            _this.document.designMode = "on";
            var res = _this.document.execCommand("italic", "false", null);
            _this.document.designMode = "off";
            var eles = _this.getCssElementArray();
            eles.each(function () {
                var el = $(this);
                _this.loopCss(el, css);
            });
        });
        this.$tool.children("#fontSize").children("select").focus(function () {
            _this.rebuildUserRange();
        }).on("change", function () {
            var v = $(this).val() + "px";
            _this.document.designMode = "on";
            _this.document.execCommand("italic", "false", null);
            _this.document.designMode = "off";
            var css = { "font-size": v };
            var eles = _this.getCssElementArray();
            eles.each(function () {
                var el = $(this);
                _this.loopCss(el, css);
            });
        });
        this.$tool.children("#isClearBackground").children("select").on("change", function () {
            var v = $(this).val();
            if (v === "1") {
                _this.clearBg = false;
            } else {
                _this.clearBg = true;
            }
        });
        this.$inputWrap.mouseleave(function () {
            _this.setDomRange();
        }).mousedown(function () {
            _this.head.children("#_selection_style").remove();
        }).on("paste", function (e) {           
            setTimeout(function () {
                console.log("粘贴 》》》》》");
                if (_this.clearBg) {
                    _this.setDomRange();
                    var r = _this.range;
                    var ancestor = r.commonAncestorContainer;
                    if (ancestor.nodeType === 3) {
                        ancestor = $(ancestor.parentNode);
                    } else {
                        ancestor = $(ancestor);
                    }
                    var wrap = _this.$input;
                    while (ancestor[0].tagName !== "PRE") {
                        wrap = ancestor;
                        ancestor = ancestor.parent();
                    }
                    //console.log("paste >>>>>>");
                    _this.clearBackground(wrap);
                }            
            }, 0);
        });
        this.$tool.children("#_clr_btn_").click(function () {
            _this.$input.html("");
        });
    },
    /***
     * 获取Dom Selection
     * **/
    getDomSelection: function () {
        var selection;
        if (this.window.getSelection) {
            selection = this.window.getSelection();
        } else if (this.document.selection) {
            selection = this.document.selection.createRange();
        }
        return selection;
    },
    /***
     * 保持Dom range
     * ***/
    setDomRange: function () {
        var seletionObj = this.getDomSelection();
        if (seletionObj.getRangeAt && seletionObj.rangeCount > 0) {
            this.range = seletionObj.getRangeAt(0);
        } else { // 老版本浏览器
            if (seletionObj.anchorNode) {
                this.range = this.document.createRange();
                this.range.setStart(seletionObj.anchorNode, seletionObj.anchorOffset);
                this.range.setEnd(seletionObj.focusNode, seletionObj.focusOffset);
            }
        }
        if (!this.range) {
            console.log("code css getDomRange 异常........^^.^^");
        }
    },
    /***
     * 根据this.range 重建 选区
     * * */
    rebuildUserRange: function () {
        if (this.range) {
            var selection = this.getDomSelection();
            try {
                selection.removeAllRanges();
            } catch (e) {
            }
            selection.addRange(this.range);
        }
    },
    /**递归修饰**/
    loopCss: function (el, css) {
        el.css(css).removeAttr("size").removeAttr("color");
        var _this = this;
        el.children().each(function () {
            _this.loopCss($(this), css);
        });
    },
    /***
     * 创建选区
     * **/
    createRange: function (firstChild, lastChild, startOffset, endOffset) {
        try {
            this.range = this.document.createRange();
            this.range.setStart(firstChild, startOffset);
            this.range.setEnd(lastChild, endOffset);
            var sel = this.window.getSelection();
            try {
                sel.removeAllRanges();
            } catch (ex) { }
            sel.addRange(this.range);
        } catch (ex) {
            console.log("error");
        }
    },
    changeSelectionColor: function (cssName, cssValue) {
        var style = '#input_txt *::selection{' + cssName + ':' + cssValue + ';background-color:#338FFF;}' +
            '#input_txt *::-moz-selection{' + cssName + ':' + cssValue + ';background-color:#338FFF;}' +
            '#input_txt *::-webkit-selection{' + cssName + ':' + cssValue + ';background-color:#338FFF;}';
        this.head.children("#_selection_style").remove();
        this.head.append("<style id='_selection_style'>" + style + "</style>");
    },
    /***
     * 获取修饰目标
     * **/
    getCssElementArray: function () {
        var barray = this.$inputWrap.find("i");
        if (barray.length === 0) {
            barray = this.$inputWrap.find("em");
        }
        barray.each(function () {
            var $t = $(this);
            var pEl = $t.parent();
            var style = "";
            if (pEl[0].tagName !== "PRE") {
                style = pEl.attr("style");
            }
            var txt = $t.text();
            var prevSibling = $t[0].previousElementSibling;
            var nextSibling = $t[0].nextElementSibling;
            if (!prevSibling && !nextSibling && pEl.children().length === pEl.contents().length) {
                pEl.text(txt).addClass("_target");
            } else {
                $t.replaceWith("<span style='" + style + "' class='_target'>" + txt + "</span>");
            }
        });
        barray = this.$inputWrap.find("._target");
        var startNode = barray.first()[0];
        var endNode = barray.last()[0];
        var endLen;
        if (endNode.childNodes) {
            endLen = endNode.childNodes.length;
        } else {
            endLen = endNode.length;
        }
        this.createRange(startNode, endNode, 0, endLen);
        setTimeout(function () {
            barray.each(function () {
                $(this).removeClass("_target");
            });
        }, 1);
        return barray;
    }
};
function FloatTools(editor) {
    $B.extend(this, FloatTools); //继承父类 
    var _this = this;
    this.editor = editor;
    this.target = undefined;
    this.wrap = $("<div tabindex='0' class='k_box_size' style='cursor:move; border: 1px solid #ccc;background: #A7CBFA;color:#fff;line-height:20px;height:20px;position:absolute;z-index:2111111111;top:-100000px;display:none;text-align:center;'>" + eConfig.label.draglabel + "</div>").appendTo(this.editor.jqObj);
    this.jqObj = this.wrap;
    var closeBtn = $("<div title='" + eConfig.label.delete + "' style='cursor:pointer;width:20px;height:20px;position:absolute;right:0;line-height:20px;top:0;text-align:center;'><i class='fa fa-cancel'></i></div>").appendTo(this.wrap);
    closeBtn.on("click", function () {
        _this.editor.$input = _this.editor.$fixInput;
        _this.editor.putFlowPanel2Undo(_this.target);
        _this.target.remove();
        _this.target = undefined;
        _this.editor._clearRangeRecord();
        _this.hide();
        _getBody().css("cursor", "default");
    });
    this.startPos = {};
    this.wrap.on("focus", function () {
        _this.rangeInfo = _this.editor._getRangeInfo();
    });
    var fixTop = 0, fixLeft = 0;
    this.wrap.draggable({
        onStartDrag: function (args) { //开始拖动
            _this.editor._setCurrentHtml();
            _this.editor.resizing = true;
            _this.wrap.css("cursor", "move");            
            _this.startPos.left = parseFloat( _this.target.css("left").replace("px" , "") );
            _this.startPos.top = parseFloat( _this.target.css("top").replace("px" , "") );
            if (_this.editor["resizeBox"]) {
                _this.editor["resizeBox"].hide();
            }
            _this.editor.removeSectionResizeBar();
        },
        onDrag: function (args) { //拖动中           
            var state = args.state;
            var data = state._data;
            var top = _this.startPos.top + data.topOffset + fixTop;
            var left = _this.startPos.left + data.leftOffset + fixLeft;
            _this.target.css({
                top: top,
                left: left
            });
        },
        onStopDrag: function (args) { //拖动结束
            _this.editor._onChange(true);
            _this.wrap.css("cursor", "move");
            _this.editor.resizing = false;
            if (_this.editor["resizeBox"]) {
                var matrix = _this.target.css("transform");
                var angle = parseFloat($B.getMatrixAngle(matrix));
                if (angle === 0) {
                    _this.editor["resizeBox"].show(_this.target);
                }
            }
            _this.editor.rebuildUserRange(_this.rangeInfo);
        },
        onMouseUp: function () {
            _this.editor._clearCurrentHtml();
            _this.editor.rebuildUserRange(_this.rangeInfo);
        }
    });
}
FloatTools.prototype = {
    constructor: FloatTools,
    show: function (target) {       
        this.target = target;
        var width = this.target.width();    
        var css = this._getPos();
        css.width = width;
        this.wrap.css(css).show();        
        this.editor.floatPropPanel.show(target);
    },
    _getPos:function(){
        var pos = this.target.position();        
        var borderL = this.editor.$inputWrap.css("border-left");
        if(borderL && borderL !== "none"){
            borderL = parseFloat( borderL.replace("px",""));
            pos.left = pos.left + borderL;
        }
        var toolbar = this.editor.jqObj.children(".k_edit_tools_wrap");
        if(toolbar.length > 0){
            pos.top = pos.top + toolbar.outerHeight();
        }
        var css = {
            top: pos.top - 16 ,
            left: pos.left 
        };
        return css;
    },
    onScroll:function(){
        if(this.wrap.css("display") !== "none"){
            var pos = this._getPos();
            this.wrap.css(pos);
        }        
    },
    hide: function () {
        this.editor.enabledFunc();
        this.editor.floatPropPanel.hide();
        this.wrap.hide();
        this.target = undefined;
        if (this.editor["resizeBox"]) {
            this.editor["resizeBox"].unbind();
            this.editor["resizeBox"].hide();
        }
    }
};
/***
 * 浮动图片/文本的属性面板
 * 设置透明度、旋转角度
 * **/
function FloatPropPanel(editor) {
    $B.extend(this, FloatPropPanel); //继承父类 
    var _this = this;
    this.editor = editor;
    this.target = undefined;
    this.wrap = $("<div style='top:-100000px;display:none;background:#fff;border: 1px solid #ccc;position:absolute;z-index:211111111111;width:250px;height:300px' class='k_box_shadow k_box_size k_float_seting_panel'></div>");
    this.jqObj = this.wrap;
    this.wrap.append("<div id='k_f1oat_pa1el_header' style='cursor:move;text-align:center;line-height:26px;border-bottom:1px solid #ccc;'>" + eConfig.label.floatSetTip + "</div>");
    this.wrap.append("<div style='text-align:left;padding-left:12px;line-height:25px;margin-top:12px;'>" + eConfig.label.floatOpacity + "<span style='padding-left:6px'></span></div>");
    var opacityDiv = $("<div style='text-align:left;padding-left:12px;line-height:25px;margin-top:6px;padding:2px 5px;' class='k_box_size'></div>").appendTo(this.wrap);
    this.wrap.append("<div style='text-align:left;padding-left:12px;line-height:25px;margin-top:12px;'>" + eConfig.label.floatAngle + "<span style='padding-left:6px;'></span></div>");
    var angleDiv = $("<div style='text-align:left;padding-left:12px;line-height:25px;margin-top:6px;padding:2px 5px;' class='k_box_size'></div>").appendTo(this.wrap);
    var shortBtns = $("<div style='padding-left:12px;margin-top:8px;'>" + eConfig.label.shortcut + "：<span v='0' style='padding:2px 4px;cursor:pointer;'>0°</span><span v='90' style='padding:2px 4px;cursor:pointer;'>90°</span><span v='180' style='padding:2px 4px;cursor:pointer;'>180°</span><span v='270' style='padding:2px 4px;cursor:pointer;'>270°</span></div>").appendTo(this.wrap);
    this.shadowBtn = $("<div style='padding-left:12px;margin-top:8px;line-height:22px;'>" + eConfig.label.isShadow + "：<input checked='checked' type='checkbox' id='_chk_shadow'/></div>").appendTo(this.wrap);
    this.wrap.append("<div style='padding-left:12px;margin-top:8px;line-height:22px;color:#766479;'>" + eConfig.label.resizeTip + "</div>");
    this.wrap.append("<div id='_z_index_it' style='padding-left:12px;margin-top:8px;line-height:22px;color:#766479;'><span>" + eConfig.label.zindex + "</span><i style='margin-left:20px;cursor:pointer;' title='" + eConfig.label.zindexTop + "' class='fa fa-up-big'></i><i style='margin-left:20px;cursor:pointer;' title='" + eConfig.label.zindexBottom + "' class='fa fa-down-big'></i></div>");
    this.wrap.appendTo(this.editor.jqObj);
    this.opacityDiv = opacityDiv;
    this.angleDiv = angleDiv;
    this.onChangeEndEvent = undefined;
    setTimeout(function () {
        opacityDiv.myslider({
            onChange: function (v) {
                _this.editor._onChange();
                opacityDiv.prev().children("span").html(v + "%");
                var opc = 1 - (v / 100);
                //console.log("onChange ==  " + opc);
                _this.target.children().first().css({
                    "-moz-opacity": opc,
                    "-khtml-opacity": opc,
                    "opacity": opc
                });
            }
        });
        angleDiv.myslider({
            start: 0,
            end: 360,
            onChange: function (v, isOnSet) {
                _this.editor._onChange();
                angleDiv.prev().children("span").html(v + "°");
                _this.target.css("transform", "rotate(" + v + "deg)");
                if (v !== 0) {
                    if (_this.editor.resizeBox) {
                        _this.editor.resizeBox.hide();
                    }
                }
                if (!isOnSet) {//避免逻辑死循环
                    clearTimeout(_this.onChangeEndEvent);
                    _this.onChangeEndEvent = setTimeout(function () {
                        if (_this.target) {
                            _this.editor.floatTools.show(_this.target);
                        }
                    }, 500);
                }
            }
        });
    }, 10);
    shortBtns.children("span").click(function () {
        var v = parseFloat($(this).attr("v"));
        _this.angleDiv.myslider("setValue", v);
        _this.editor.floatTools.show(_this.target);
    });
    this.shadowBtn = this.shadowBtn.find("input").click(function () {
        var isChk = $(this).prop("checked");
        if (_this.target) {
            if (isChk) {               
                _this.target.css({
                    "-moz-box-shadow": "0px 0px 3px 3px #D8D8D8",
                    "-webkit-box-shadow": "0px 0px 3px 3px #D8D8D8",
                    "box-shadow": "0px 0px 3px 3px #D8D8D8"
                }).addClass("k_box_shadow");
            } else {
                _this.target.css({
                    "-moz-box-shadow": "none",
                    "-webkit-box-shadow": "none",
                    "box-shadow": "none"
                }).removeClass("k_box_shadow");
            }
        }
    });
    //层级
    var tmpWrap = this.wrap.children("#_z_index_it");
    tmpWrap.find(".fa-down-big").click(function () {
        if (_this.target) {
            var zindex = parseInt(_this.target.css("z-index"));
            var minIndex;
            _this.target.siblings(".k_edit_float_panel").each(function () {
                var idx = parseInt($(this).css("z-index"));
                if (!minIndex) {
                    minIndex = idx;
                } else if (idx < minIndex) {
                    minIndex = idx;
                }
            });
            if (minIndex <= zindex) {
                var newIdx = minIndex - 1;
                _this.target.css("z-index", newIdx);
                var fchild = _this.target.children().first();
                var nextEl = fchild.css("z-index", newIdx).next();
                nextEl.css("z-index", minIndex);
                if (nextEl.hasClass("k_editor_float_img_wrap")) {//图片
                    var $img = nextEl.children("img").css("z-index", minIndex);
                    $img.next().css("z-index", minIndex + 1);
                }
            }
        }
    });
    tmpWrap.find(".fa-up-big").click(function () {
        if (_this.target) {
            var zindex = parseInt(_this.target.css("z-index"));
            var maxIndex;
            _this.target.siblings(".k_edit_float_panel").each(function () {
                var idx = parseInt($(this).css("z-index"));
                if (!maxIndex) {
                    maxIndex = idx;
                } else if (idx > maxIndex) {
                    maxIndex = idx;
                }
            });
            if (maxIndex >= zindex) {
                var newIdx = maxIndex + 1;
                _this.target.css("z-index", newIdx);
                var fchild = _this.target.children().first();
                var nextEl = fchild.css("z-index", newIdx).next();
                var topIndex = newIdx + 1;
                nextEl.css("z-index", topIndex);
                if (nextEl.hasClass("k_editor_float_img_wrap")) {//图片
                    var $img = nextEl.children("img").css("z-index", topIndex);
                    $img.next().css("z-index", topIndex + 1);
                }
            }
        }
    });
    //浮动面板可拖动功能
    this.wrap.draggable({
        handler: this.wrap.children("#k_f1oat_pa1el_header")
    });
}
FloatPropPanel.prototype = {
    constructor: FloatPropPanel,
    show: function (target) {
        if(this.target && this.target[0] === target[0]){
            return;
        }
        this.target = target;
        if (this.target.hasClass("k_box_shadow")) {
            this.shadowBtn.prop("checked", true);
        } else {
            this.shadowBtn.prop("checked", false);
        }        
        if (this.wrap.css("display") === "none") {
            this.wrap.css({
                top: 60 ,
                right: 50 
            }).show();
        }
        var matrix = this.target.css("transform");
        var angle = parseFloat($B.getMatrixAngle(matrix));
        if (angle < 0) {
            angle = angle + 360;
        }
        var opacity = Math.round((1 - parseFloat(this.target.children().first().css("opacity"))) * 100);
        var _this = this;
        setTimeout(function () {
            _this.opacityDiv.myslider("setValueSilent", opacity);
            _this.angleDiv.myslider("setValueSilent", angle);
        }, 1);
    },
    hide: function () {
        this.wrap.hide();
        this.target = undefined;
    }
};
function Stack(size) {
    $B.extend(this, Stack); //继承父类 
    this.record = new Array(size);
    this.size = size; //栈大小
    this.length = 0; //当前记录的长度
    window["_b_u_zindex___"]=-100;
}
Stack.prototype = {
    constructor: Stack,
    /**压入记录
     * 返回当前栈长度
     * **/
    push: function (data) {
        //栈满，移除底部一个记录
        if (this.length === this.size) {
            this.record.pop();
            this.length--;
        }
        var l = this.record.unshift(data);
        this.length++;
        if (this.length > this.size) {
            this.length = this.size;
        }
        return this.length;
    },
    /**记录出栈
     * 返回一个记录
     * **/
    pop: function () {
        this.length--;
        if (this.length < 0) {
            this.length = 0;
        }
        return this.record.shift();
    },
    /**清空栈**/
    clear: function () {
        this.record = new Array(this.size);
        this.length = 0;
    },
    /**循环记录**/
    each: function (fn) {
        var len = this.length;
        for (var i = 0; i < len; i++) {
            fn(this.record[i], i);
        }
    },
    /**
     * 获取当前栈大小
     * **/
    getLength: function () {
        return this.length;
    }
};
//表格控件
function Table(edit) {
    this.edit = edit;
    this.className = "table";
    this.selectBackground = "#F0F0F0";
    var _this = this;
    this.clickTd = undefined;
    this.movingTd = undefined;
    this.mutilSelectBackground = {};
    this.menu = getSingleton("TableProps", edit);
    this.width = undefined;
    this.height = undefined;
    this.onlyUpdateHeight = false;
    this.onlyUpdateWidth = false;
    this.selectTdArray = [];
}
Table.prototype = {
    constructor: Table,
    initByJq: function (jqObj) {
        this.table = jqObj;
        this.jqObj = this.table;
        this.tbody = this.table.children();
        var events = this._getTdEvents();
        this.resetTableIndex(function (td) {
            td.on(events);
        });
        var _this = this;
        setTimeout(function () {
            _this.reSize(true);
        });
        this.contenteditableTxt = this.table.parent();
        //根据k_edit_table_selected_td 创建 mutilSelectBackground 
        _this.mutilSelectBackground = {};
        var tdArray = this.tbody.children().children("td.k_edit_table_selected_td");
        var cssTdArray = [];
        tdArray.each(function () {
            var td = $(this);
            var bgColor = td.attr("bgcolor");
            _this.mutilSelectBackground[td.attr("row") + "_" + td.attr("col")] = {
                "td": td,
                "background": bgColor
            };
            cssTdArray.push(td);
        });
        this.selectTdArray = cssTdArray;
        this.jqObj.data("object", this); //记录对应的对象实例
        fixIeResizeBug(this.jqObj[0]);
        return this;
    },
    resetTableIndex: function (onForeachFn) {
        var trs = this.tbody.children();
        var posArray = [];
        var posMap = {};
        trs.each(function () {
            var tr = $(this);
            tr.children().each(function () {
                var td = $(this);
                var ofs = td.offset();
                if (!posMap[ofs.left]) {
                    posMap[ofs.left] = 1;
                    posArray.push(ofs.left);
                }
            });
        });
        posArray.sort(function (a, b) {
            return a - b;
        });
        var colNum = 0;
        var call = typeof onForeachFn === "function";
        trs.each(function (j) {
            var tr = $(this);
            tr.attr("id", "row_" + j);
            var tdCount = 0;
            tr.children().each(function (i) {
                tdCount++;
                var td = $(this);
                var colspan = td.attr("colspan");
                if (colspan) {
                    colspan = parseInt(colspan) - 1;
                    while (colspan > 0) {
                        tdCount++;
                        colspan--;
                    }
                }
                var left = td.offset().left;
                var idx;
                for (var k = 0, len = posArray.length; k < len; ++k) {
                    if ((left - 2) <= posArray[k] && posArray[k] <= (left + 2)) {//兼容1 像数差异问题
                        idx = k;
                        break;
                    }
                }
                td.addClass("k_box_size");
                td.attr({
                    "tabindex": 0,
                    "row": j,
                    "col": i,
                    "index": idx
                });
                if (call) {
                    onForeachFn(td);
                }
            });
            if (tdCount > colNum) {
                colNum = tdCount;
            }
        });
        this.rowNum = trs.length;
        this.colNum = colNum;
    },
    init: function (colNum, rowNum) {
        var tdEvents = this._getTdEvents();
        this.table = $("<table  class='k_box_size' style='border-collapse:collapse;width:100%;height:auto;'><tbody></tbody></table>");
        this.jqObj = this.table;
        this.tbody = this.table.children();
        for (var i = 0; i < rowNum; ++i) {
            var tr = this._createTr({
                "id": "row_" + i
            });
            for (var j = 0; j < colNum; ++j) {
                var td = this._createTd({
                    "tabindex": "0",
                    "row": i,
                    "col": j,
                    "index": j
                }, eConfig.table.tdCss);
                tr.append(td);
                td.on(tdEvents);
            }
            this.tbody.append(tr);
        }
        this.colNum = colNum;
        this.rowNum = rowNum;
        var _this = this;
        setTimeout(function () {
            _this._activedFirstTd();
        }, 10);
        _this.jqObj.data("object", _this); //记录对应的对象实例
        fixIeResizeBug(this.jqObj[0]);
        return this;
    },
    _hideAdd: function () {
        if (this.$addBtn) {
            this.$addBtn.hide();
            this.$addBtn.removeData("table");
            this.$addBtn.removeData("target");
        }
    },
    _showAdd: function (target, ofs, title) {
        var _this = this;
        if (!this.$addBtn) {
            this.$addBtn = _getBody().children("#k_edit_table_addbtn");
            if (this.$addBtn.length === 0) {
                var $addBtn = $("<div id='k_edit_table_addbtn' title='" + title + "' style='cursor:pointer;background:none;width:14px;height:14px;top:-1000px;position:absolute;z-index:9999999999;display:none;'><i style='font-size:12px' class='fa fa-plus'></i></div>");
                this.$addBtn = $addBtn.appendTo(_getBody()).click(function () {
                    var $t = $(this);
                    var tabObj = $t.data("table");
                    var itarget = $t.data("target");
                    $t.hide();
                    $t.removeData("table");
                    $t.removeData("target");
                    var srcTd;
                    if (itarget[0].tagName === "TD") {
                        srcTd = tabObj.clickTd;
                        tabObj.clickTd = itarget;
                        tabObj.insertColFn("r");
                        tabObj.clickTd = srcTd;
                    } else {
                        srcTd = tabObj.clickTd;
                        tabObj.clickTd = itarget.children().first();
                        tabObj.insertRowFn("b");
                        tabObj.clickTd = srcTd;
                    }
                });
            }
        }
        this.$addBtn.data("table", this).attr("title", title);
        this.$addBtn.data("target", target);
        this.$addBtn.css(ofs).show();
        clearTimeout(this.addBtnHideTimer);
        this.addBtnHideTimer = setTimeout(function () {
            if (_this.$addBtn) {
                _this.$addBtn.hide();
                _this.$addBtn.removeData("table");
                _this.$addBtn.removeData("target");
            }
        }, 2500);
    },
    _getTdEvents: function () {
        if (!this.tdEvents) {
            var _this = this;
            var splitXPos, splitYPos, splitLine;
            var targetRow, undoData;
            var mutilSelect = false;
            var tdEvents = {
                mouseup: function (e) {
                    var tmpArr = [];
                    if ($.isEmptyObject(_this.mutilSelectBackground)) { //非多选
                        tmpArr.push(_this.clickTd);
                        if (e.which === 3 && e.target.nodeName !== "A") {
                            _this.showMenu(e);
                        } else {//移动功能
                            var td = $(this);
                            var parent = td.parent();
                            while (parent.length > 0) {
                                if (parent[0].tagName === "DIV") {
                                    break;
                                }
                                parent = parent.parent();
                            }
                            var eles = [parent];
                            _this.edit._setMovingTargets(eles, false);
                        }
                    } else {
                        _this.edit.clearUserRange(true);
                        _this.foreachSeletedTds(function (rec) {
                            tmpArr.push(rec.td);
                        });
                        _this.clearClickTd();
                        e["mutils"] = true;
                        _this.showMenu(e);
                    }
                    _this.selectTdArray = tmpArr;
                    _this.edit.clickActivedObject = _this;
                    mutilSelect = false;
                    _this.movingTd = undefined;
                },
                mousemove: function (e) {
                    var td = $(this);
                    var ofs = td.offset();
                    var w = td.outerWidth();
                    var h = td.outerHeight();
                    var endOfs = {
                        top: ofs.top + h,
                        left: ofs.left + w
                    };
                    var row = parseInt(td.attr("row"));
                    var col = parseInt(td.attr("col"));
                    var id = row + "_" + col;
                    if (mutilSelect) {
                        if (!_this.movingTd) {
                            _this.movingTd = td;
                        } else {
                            var movingId = _this.movingTd.attr("row") + "_" + _this.movingTd.attr("col");
                            if (movingId !== id) {
                                _this.movingTd = td;
                                _this.makeSelectedUi();
                                //清除document中的选择区域
                                if (document.selection) {
                                    document.selection.empty();
                                } else if (window.getSelection) {
                                    window.getSelection().removeAllRanges();
                                }
                                return false;
                            }
                        }
                    }
                    targetRow = undefined;
                    splitXPos = undefined;
                    splitYPos = undefined;
                    var mouseX = e.pageX;
                    var mouseY = e.pageY;
                    _this.table.css("cursor", "default");
                    _this.contenteditableTxt.removeAttr("contenteditable");
                    var startXshift = mouseX - ofs.left;
                    var endXshift = endOfs.left - mouseX;
                    if (startXshift <= 5 || endXshift <= 5) {
                        if (startXshift <= 5) {
                            splitXPos = ofs;
                        } else {
                            splitXPos = endOfs;
                        }
                    }
                    if (splitXPos) {
                        _this.table.css("cursor", "w-resize");
                        _this.contenteditableTxt.attr("contenteditable", false);
                    } else { //行高拖动                   
                        var startYshift = mouseY - ofs.top;
                        var endYshift = endOfs.top - mouseY;
                        if (startYshift <= 5 || endYshift <= 5) {
                            var currentRow = td.parent();
                            if (startYshift <= 5) {
                                targetRow = currentRow.prev();
                                splitYPos = {
                                    "top": ofs.top
                                };
                            } else {
                                splitYPos = {
                                    "top": endOfs.top
                                };
                                targetRow = currentRow;
                            }
                            if (splitYPos) {
                                _this.table.css("cursor", "s-resize");
                                _this.contenteditableTxt.attr("contenteditable", false);
                            }
                        }
                    }
                    //检查提示全选按钮
                    var isLastCol = _this.colNum === (col + 1);
                    var isLastRow = _this.rowNum === (row + 1);
                    var mouseOfs = {
                        top: e.pageY,
                        left: e.pageX
                    };
                    if (row === 0) {
                        if (col === 0) {
                            //左上角方向
                            if (e.pageX <= (ofs.left + 50)) {
                                _this._showAnchor({
                                    col: col,
                                    row: row,
                                    isLastRow: isLastRow,
                                    isLastCol: isLastCol
                                }, ofs, endOfs, mouseOfs);
                            } else {
                                _this._hideAnchor();
                            }
                        }
                    } else {
                        _this._hideAnchor();
                    }
                    //快捷插入行列 _showAdd(target, ofs) insertCol insertRow 
                    var tableOfs = _this.table.offset();
                    var insertTarget, tPos, tipTitle;
                    if (row === 0) {
                        if ((endOfs.left - 12) <= mouseOfs.left && mouseOfs.left <= endOfs.left) {
                            insertTarget = td;
                            if (insertTarget.next().length > 0) {
                                tPos = { left: endOfs.left - 4, top: ofs.top - 12 };
                                tipTitle = eConfig.table.insertCol;
                            }
                        } else if ((ofs.left - 12) <= mouseOfs.left && mouseOfs.left <= (ofs.left + 12)) {
                            insertTarget = td.prev();
                            if (insertTarget.length > 0) {
                                tPos = { left: ofs.left - 4, top: ofs.top - 12 };
                                tipTitle = eConfig.table.insertCol;
                            }
                        }
                    }
                    if (col === 0 && mouseOfs.left <= (ofs.left + 20)) {
                        if ((endOfs.top - 12) <= mouseOfs.top && mouseOfs.top <= endOfs.top) {
                            insertTarget = td.parent();
                            tPos = { left: ofs.left - 5, top: endOfs.top - 12 };
                            tipTitle = eConfig.table.insertRow;
                        } else if ((ofs.top - 12) <= mouseOfs.top && mouseOfs.top <= (ofs.top + 12)) {
                            var prevRow = td.parent().prev();
                            if (prevRow.length > 0) {
                                insertTarget = prevRow;
                                tPos = { left: ofs.left - 5, top: ofs.top - 12 };
                                tipTitle = eConfig.table.insertRow;
                            }
                        }
                    }
                    if (insertTarget && tPos) {
                        if (insertTarget[0].tagName === "TR") {
                            if (insertTarget.children().first().attr("index") !== "0") {
                                return false;
                            }
                        }
                        _this._showAdd(insertTarget, tPos, tipTitle);
                    } else {
                        _this._hideAdd();
                    }
                },
                mousedown: function (e) {
                    stopDefaultctxMenu();
                    if (navigator.userAgent.indexOf("Firefox") > 0) {
                        document.designMode = "on";
                        document.execCommand('enableObjectResizing', false, 'false');
                        document.designMode = "off";
                    }
                    _this.clearSelected(true); //清空现在 
                    _this.clickTd = $(this).addClass("k_edit_selected_td_shadow");
                    if (e.which === 3) {
                        stopDefaultctxMenu();
                        return false;
                    }
                    mutilSelect = false;
                    var dragOpts,
                        $body = _getBody();
                    if (splitXPos || splitYPos) {
                        dragOpts = {
                            nameSpace: 'dragsplit', //命名空间，一个对象可以绑定多种拖动方式
                            which: 1, //鼠标键码，是否左键1,右键3 才能触发拖动，默认左右键均可
                            cursor: 'move',
                            axis: 'h',
                            onStartDrag: function (args) { //开始拖动
                                _this.edit._onChange();
                            },
                            onStopDrag: function (args) {
                                /***偏移量***/
                                var state = args.state;
                                var moveData = state._data;
                                var leftOffset = moveData.leftOffset;
                                var topOffset = moveData.topOffset;
                                var data = state.target.data("data");
                                var tableOfs = _this.jqObj.offset();
                                var putUndo = false;
                                if (leftOffset !== 0) {
                                    var compareXpoit = data;
                                    var trArray = _this.tbody.children();
                                    var startx = compareXpoit - 5;
                                    var endx = compareXpoit + 5;
                                    trArray.each(function () {
                                        $(this).children().each(function () {
                                            var td = $(this);
                                            var outerWidth = td.outerWidth();
                                            var endPoit = Math.round( td.offset().left );
                                            var startPoit = endPoit + outerWidth;
                                            var innerWidth, newWidth;
                                            if (startPoit <= endx && startPoit >= startx) {
                                                innerWidth = td.data("width");
                                                newWidth = innerWidth + leftOffset;
                                                td.data("width", newWidth).attr("w", newWidth);
                                                return true;
                                            }
                                            if (endPoit >= startx && endPoit <= endx) {
                                                innerWidth = td.data("width");
                                                newWidth = innerWidth - leftOffset;
                                                td.data("width", newWidth).attr("w", newWidth);
                                                return false;
                                            }
                                            if (endPoit > endx) {
                                                return false;
                                            }
                                        });
                                    });
                                    _this.onlyUpdateWidth = true;
                                    _this.setSize();
                                    _this.onlyUpdateWidth = false;
                                    putUndo = true;
                                } else if (topOffset !== 0) {
                                    if (data.targetRow.length > 0) {
                                        var rowspanTds = _this._getRowspanTds(data.targetRow);
                                        data.targetRow.children().each(function (i) {
                                            var td = $(this);
                                            var height = td.data("height") + topOffset;
                                            td.data("height", height).attr("h", height);
                                        });
                                        Object.keys(rowspanTds).forEach(function (key) {
                                            var td = rowspanTds[key];
                                            var height = td.data("height") + topOffset;
                                            td.data("height", height).attr("h", height);
                                        });
                                    }
                                    _this.onlyUpdateHeight = true;
                                    _this.setSize();
                                    _this.onlyUpdateHeight = false;
                                    putUndo = true;
                                }
                                state.target.remove();
                                splitLine = undefined;
                                if (putUndo) {
                                    _this.edit._putUndo();
                                }
                                _this.edit.moveToEnd(_this.clickTd);
                            }
                        };
                    } else {
                        mutilSelect = true;
                    }
                    if (splitXPos) { //列宽拖动 
                        //避免出现滚动条影响坐标
                        var top = _this.table.offset().top;
                        var bHeight = $body.height();
                        var diff = bHeight - (top + _this.height);
                        var sliptHeight = _this.height;
                        if(diff < 1){
                            sliptHeight = sliptHeight + diff;
                        }                       
                        splitLine = $("<div style='cursor:w-resize;left:" + splitXPos.left + "px;top:" + top + "px;position:absolute;height:" + sliptHeight + "px;width:2px;border-left:1px solid #FF000D;z-index:999999'/>");
                        splitLine.appendTo($body);
                        splitLine.data("data", splitXPos.left);
                        dragOpts.cursor = "w-resize";
                    } else if (splitYPos) { //行高拖动
                        splitYPos["left"] = _this.table.offset().left;
                        dragOpts["axis"] = "v";
                        splitLine = $("<div style='cursor:s-resize;left:" + splitYPos.left + "px;top:" + splitYPos.top + "px;position:absolute;height:3px;width:" + _this.table.outerWidth() + "px;border-top:1px solid #FF000D;z-index:99999999'/>");
                        splitLine.appendTo($body);
                        dragOpts.cursor = "s-resize";
                        splitLine.data("data", {
                            "targetRow": targetRow
                        });
                    }
                    if (splitLine) {
                        dragOpts["onStartDrag"] = function () {
                            //_this.table.attr("contenteditable","false");
                            _this.edit.moveToEnd(_this.clickTd);
                            undoData = _this.edit._makeUndoDataByFocus();
                        };
                        dragOpts["onMouseUp"] = function () {
                            splitLine.remove();
                            splitLine = undefined;
                            _this.edit.moveToEnd(_this.clickTd);
                        };
                        splitLine.draggable(dragOpts).trigger("mousedown.dragsplit", {
                            pageX: e.pageX,
                            pageY: e.pageY,
                            which: e.which
                        });
                        _this.menu.hide();
                        _this.$splitLine = splitLine;
                    }
                    _this.menu.hide();
                },
                click: function () {
                    return false;//避免冒泡edit.$input.click
                },
                dblclick: function () {
                    if (_this.clickTd) {
                        var pEl = _this.clickTd.children("p");
                        _this.edit.createCrossRange(pEl.first(), pEl.last());
                        _this.edit.saveUserRange();
                        //console.log("td dblclick >>>>>>>>>>>>>>");
                    }
                }
            };
            this.tdEvents = tdEvents;
        }
        return this.tdEvents;
    },
    hideMenu: function () {
        if (this.menu) {
            this.menu.hide();
        }
    },
    selectAllTd: function (left, top) {
        var _this = this;
        var trs = this.tbody.children();
        this.clickTd = trs.first().children().first();
        _this.selectTdArray = [];
        trs.each(function (i) {
            var tr = $(this);
            tr.children().each(function (j) {
                var td = $(this);
                var bgColor = td.css("background-color");
                td.css("background-color", _this.selectBackground).addClass("k_edit_table_selected_td");
                td.attr("bgcolor", bgColor);
                _this.selectTdArray.push(td);
                _this.mutilSelectBackground[td.attr("row") + "_" + td.attr("col")] = {
                    "td": td,
                    "background": bgColor
                };
            });
        });
        this.showMenu({
            pageX: left,
            pageY: top,
            mutils: true
        });
    },
    _showAnchor: function (args, ofs, endOfs, mouseOfs) {
        var _this = this;
        if (!this.$anchor) {
            this.$anchor = _getBody().children("#k_edit_table_anchor");
            if (this.$anchor.length === 0) {
                var $anchor = $("<div id='k_edit_table_anchor' title='" + eConfig.table.anchorTitle + "' style='cursor:pointer;background:#none;width:14px;height:14px;top:-1000px;position:absolute;z-index:9999999999;display:none;'><i class='fa fa-down-hand'></i></div>");
                this.$anchor = $anchor.appendTo(_getBody()).click(function () {
                    var $t = $(this);
                    var tabObj = $t.data("table");
                    var menuPos = $t.data("menuPos");
                    tabObj.selectAllTd(menuPos.left, menuPos.top);
                    $t.removeData("table");
                    $t.removeData("menuPos");
                    $t.hide();
                    tabObj.edit.clickActivedObject = tabObj;
                });
            }
        }
        this.$anchor.data("table", this);
        var pos = {};
        var cls = "";
        if (args.row === 0) { //第一行
            pos.top = ofs.top - 20;
            pos.left = mouseOfs.left;
            cls = 'fa-down-hand';
        } else if (args.isLastRow) { //最后一行
            pos.top = endOfs.top;
            pos.left = mouseOfs.left;
            cls = 'fa-hand-o-up';
        } else if (args.col === 0) {
            pos.left = ofs.left - 20;
            pos.top = mouseOfs.top;
            cls = 'fa-hand-o-right';
        } else if (args.isLastCol) {
            pos.left = endOfs.left;
            pos.top = mouseOfs.top;
            cls = 'fa-hand-o-left';
        }
        this.$anchor.css(pos).children("i").attr("class", "fa " + cls);
        this.$anchor.show().data("menuPos", ofs);
        clearTimeout(this.anchorHideTimer);
        this.anchorHideTimer = setTimeout(function () {
            if (_this.$anchor) {
                _this.$anchor.hide();
                _this.$anchor.removeData("table");
                _this.$anchor.removeData("menuPos");
            }
        }, 2500);
    },
    _hideAnchor: function () {
        if (this.$anchor) {
            this.$anchor.hide();
            this.$anchor.removeData("table");
            this.$anchor.removeData("menuPos");
        }
    },
    _getRowspanTds: function (targetRow) {
        var rowEndIdx = parseInt(targetRow.attr("id").replace("row_", ""));
        var colRec = {};
        var prevRow = targetRow.prev();
        while (prevRow.length > 0) {
            var childs = prevRow.children();
            for (var i = 0, len = childs.length; i < len; ++i) {
                var td = $(childs[i]);
                var index = td.attr("index");
                var rowspan = td.attr("rowspan");
                if (rowspan && !colRec[index]) {
                    var rowNum = parseInt(td.attr("row"));
                    var rowIdx = rowNum + parseInt(rowspan) - 1;
                    if (rowEndIdx <= rowIdx) {
                        colRec[index] = td;
                    }
                }
            }
            prevRow = prevRow.prev();
        }
        return colRec;
    },
    css2Siblings: function (td) {
        var prevTd = td.prev();
        var nextTd = td.next();
        var row = td.parent();
        var prevRow = row.prev();
        //var nextRow = row.next();
        var borderTop = td.css("border-top");
        var borderRight = td.css("border-right");
        var borderBottom = td.css("border-bottom");
        var borderLeft = td.css("border-left");
        nextTd.css("border-left", borderRight);
        prevTd.css("border-right", borderLeft);
        var index = parseInt(td.attr("index"));
        prevRow.children().each(function () {
            var _td = $(this);
            var idx = parseInt(_td.attr("index"));
            if (index === idx) {
                _td.css("border-bottom", borderTop);
                return false;
            }
            if (idx > index) {
                return false;
            }
        });
        nextTd.children().each(function () {
            var _td = $(this);
            var idx = parseInt(_td.attr("index"));
            if (index === idx) {
                _td.css("border-top", borderBottom);
                return false;
            }
            if (idx > index) {
                return false;
            }
        });
    },
    cssSubscribe: function (params) {
        var css = params["css"];
        var _this = this;
        //全表            
        if (params["target"] === "1") {
            var trs = this.table.css(css).children().children();
            var trLength = trs.length - 1;
            trs.each(function (i) {
                var tr = $(this);
                var tds = tr.children();
                var tdLength = tds.length - 1;
                tds.each(function (j) {
                    var td = $(this);
                    if (i === 0 || i === trLength) {
                        if (i === 0) {
                            td.css("border-top", css["border-top"]);
                        } else {
                            td.css("border-bottom", css["border-bottom"]);
                        }
                        if (j === 0) {
                            td.css("border-left", css["border-left"]);
                        } else if (j === tdLength) {
                            td.css("border-right", css["border-right"]);
                        }
                    } else {
                        if (j === 0) {
                            td.css("border-left", css["border-left"]);
                        } else if (j === tdLength) {
                            td.css("border-right", css["border-right"]);
                        }
                    }
                });
            });
        } else {
            if ($.isEmptyObject(this.mutilSelectBackground)) {
                this.clickTd.css(css);
                this.css2Siblings(this.clickTd);
            } else {
                this.foreachSeletedTds(function (rec) {
                    rec["td"].css(css);
                    _this.css2Siblings(rec["td"]);
                });
            }
        }
        clearTimeout(this.reSizeTimer);
        this.reSizeTimer = setTimeout(function () {
            _this.reSize();
        }, 300);
    },
    clickSubscribe: function (edit) {
        this.clearSelected(true);
        this.menu.hide();
    },
    makeSelectedUi: function () {
        if (!this.clickTd) {
            return;
        }
        var row0 = parseInt(this.clickTd.attr("row"));
        var col0 = parseInt(this.clickTd.attr("index"));
        var row1 = parseInt(this.movingTd.attr("row"));
        var col1 = parseInt(this.movingTd.attr("index"));
        var rowspan = this.movingTd.attr("rowspan");
        var colspan = this.movingTd.attr("colspan");
        if(rowspan){
            row1 = row1 + parseInt(rowspan) - 1;
        }
        if(colspan){
            col1 = col1 + parseInt(colspan) - 1;
        }
        this.clearSelected();
        var _this = this;
        var startRow, startCol, endRow, endCol;
        if (row1 > row0) {
            startRow = row0;
            endRow = row1;
        } else {
            startRow = row1;
            endRow = row0;
        }
        if (col1 > col0) {
            startCol = col0;
            endCol = col1;
        } else {
            startCol = col1;
            endCol = col0;
        }
        _this.selectTdArray = [];
        this.tbody.children().each(function (i) {
            if (i < startRow || i > endRow) {
                return true;
            }
            var tr = $(this);
            tr.children().each(function (j) {
                var td = $(this);
                var colIdx = parseInt(td.attr("index"));
                if (colIdx < startCol || colIdx > endCol) {
                    return true;
                }
                var bgColor = td.css("background-color");
                td.css("background-color", _this.selectBackground).addClass("k_edit_table_selected_td");
                td.attr("bgcolor", bgColor);
                _this.selectTdArray.push(td);
                _this.mutilSelectBackground[td.attr("row") + "_" + td.attr("col")] = {
                    "td": td,
                    "background": bgColor
                };
            });
        });
    },
    showSplitMerge: function (txt) {
        var tr = this.menu.jqObj.find("#_split_merge_td_").show();
        var $a = tr.find("a").text(txt);
        if (txt === eConfig.table.splitTd) {
            $a.data("flag", "splitFn");
        } else {
            $a.data("flag", "mergeFn");
        }
    },
    hideSplitMerge: function () {
        this.menu.jqObj.find("#_split_merge_td_").hide();
    },
    showMenu: function (e) {
        this.hideSplitMerge();
        var ofs = {
            top: e.pageY,
            left: e.pageX
        };
        var i, j, len;
        var body = _getBody();
        var bodyHeight = body.height();
        var bodyWidth = body.width();
        var useWidth = bodyWidth - ofs.left;
        if (useWidth < 300) {
            ofs.left = bodyWidth - 310;
        }
        var useHeight = bodyHeight - ofs.top;
        if (useHeight < 200) {
            ofs.top = ofs.top - 200;
        }
        this.menu.show(ofs).setTarget(this);
        var chkTable = this.menu.jqObj.find("#_target_table_1"); //
        var chkTd = this.menu.jqObj.find("#_target_cell_1"); //
        if (e.mutils) {
            chkTable.removeAttr("checked");
            chkTd.prop("checked", "checked").prop("disabled", false);
        } else {
            chkTable.prop("checked", "checked").prop("disabled", false);
            chkTd.removeAttr("checked");
        }
        if ($.isEmptyObject(this.mutilSelectBackground)) {
            if (this.clickTd.attr("colspan") || this.clickTd.attr("rowspan")) {
                this.showSplitMerge(eConfig.table.splitTd);
            }
        } else {
            var _this = this,
                isShow = true;
            //检查是连续的可合并的单元格集合 
            /*****每一行、列都必须有相同数量的td才能合并******/
            var colTdCounter = {};
            var rowTdCounter = {};
            this.foreachSeletedTds(function (rec) {
                var td = rec.td;
                var col = parseInt(td.attr("index"));
                var row = parseInt(td.attr("row"));

                var rowspan = td.attr("rowspan");
                var colspan = td.attr("colspan");
                var rspan = 0,
                    clspan = 0;
                if (rowspan) {
                    rspan = parseInt(rowspan) - 1;
                }
                if (colspan) {
                    clspan = parseInt(colspan) - 1;
                }
                if (colTdCounter[col]) {
                    colTdCounter[col] = colTdCounter[col] + 1 + rspan;
                } else {
                    colTdCounter[col] = 1 + rspan;
                }
                if (rowTdCounter[row]) {
                    rowTdCounter[row] = rowTdCounter[row] + 1 + clspan;
                } else {
                    rowTdCounter[row] = 1 + clspan;
                }
                var tmp = rspan;
                while (tmp > 0) {
                    row = row + 1;
                    if (rowTdCounter[row]) {
                        rowTdCounter[row] = rowTdCounter[row] + 1 + clspan;
                    } else {
                        rowTdCounter[row] = 1 + clspan;
                    }
                    tmp = --tmp;
                }
                tmp = clspan;
                while (tmp > 0) {
                    col = col + 1;
                    if (colTdCounter[col]) {
                        colTdCounter[col] = colTdCounter[col] + 1 + rspan;
                    } else {
                        colTdCounter[col] = 1 + rspan;
                    }
                    tmp = --tmp;
                }
            });
            //这里的逻辑有问题                
            var count, idx, c;
            var keyArray = Object.keys(colTdCounter);
            for (i = 0, len = keyArray.length; i < len; ++i) {
                idx = parseInt(keyArray[i]);
                if (i < len - 1) {
                    if (idx !== (parseInt(keyArray[i + 1]) - 1)) {
                        isShow = false;
                        break;
                    }
                }
                c = colTdCounter[idx];
                if (!count) {
                    count = c;
                } else {
                    if (count !== c) {
                        isShow = false;
                        break;
                    }
                }
            }
            if (isShow) {
                count = undefined;
                keyArray = Object.keys(rowTdCounter);
                for (j = 0, len = keyArray.length; j < len; ++j) {
                    idx = parseInt(keyArray[j]);
                    if (j < len - 1) {
                        if (idx !== (parseInt(keyArray[j + 1]) - 1)) {
                            isShow = false;
                            break;
                        }
                    }
                    c = rowTdCounter[idx];
                    if (!count) {
                        count = c;
                    } else {
                        if (count !== c) {
                            isShow = false;
                            break;
                        }
                    }
                }
                if (isShow) {
                    this.showSplitMerge(eConfig.table.megerTd);
                }
            }
        }
    },
    clearClickTd: function () {
        if (this.clickTd) {
            //console.log(" clearClickTd clearClickTd clearClickTd");
            this.clickTd.removeClass("k_edit_selected_td_shadow");
            this.clickTd = undefined;
        }
    },
    setClickTd: function (td) {
        this.clearClickTd();
        td.addClass("k_edit_selected_td_shadow");
        this.clickTd = td;
    },
    foreachSeletedTds: function (fn) {
        var _this = this;
        var hasLoop = false;
        Object.keys(this.mutilSelectBackground).forEach(function (key) {
            fn(_this.mutilSelectBackground[key]);
            hasLoop = true;
        });
        return hasLoop;
    },
    clearSelected: function (clearClickTd) {
        if (clearClickTd) {
            this.clearClickTd();
        }
        var _this = this;
        this.foreachSeletedTds(function (rec) {
            var bgColor = rec["td"].css("background-color"); //selectBackground
            var hexColor = bgColor.toHexColor();
            if (hexColor === _this.selectBackground) {
                rec["td"].css("background-color", rec["background"]);
            }
        });
        this.mutilSelectBackground = {};
        this.edit.clearSelectedTd();
    },
    /**
     * 提取td大小,保存到 data
     * * */
    saveSize: function () {
        this.tbody.children().each(function (r) {
            var tr = $(this).attr("id", "row_" + r);
            tr.children().each(function (c) {
                var td = $(this);
                td.attr("col", c).attr("row", r);
                var w = td.innerWidth();
                var h = td.innerHeight();
                td.data("width", w).attr("w", w);
                td.data("height", h).attr("h", h);
            });
        });
    },
    /***
     * 根据 data(widht/height)设置大小
     * ***/
    setSize: function (exeIdm) {
        var _this = this;
        this.table.width("auto");
        this.table.height("auto");
        var trArray = this.tbody.children();
        trArray.each(function (i) {
            var tr = $(this);
            var tdArr = tr.children();
            tdArr.each(function () {
                var td = $(this);
                if (!_this.onlyUpdateWidth) {
                    var h = td.data("height");
                    if (h < 24) {
                        td.css("line-height", (h - 2) + "px");
                    } else {
                        td.css("line-height", "21px");
                    }
                    td.innerHeight(h);
                }
                if (!_this.onlyUpdateHeight) {
                    var w = td.data("width");
                    td.innerWidth(w);
                }
            });
        });
        var f = function () {
            var w = _this.table.outerWidth();
            var h = _this.table.outerHeight();
            _this.height = h;
            _this.width = w;
            _this.saveSize();
        };
        if (exeIdm) {
            f();
        } else {
            setTimeout(f, 2);
        }
    },
    /**
     * saveSize(提取真是大小) >>> setSize
     * **/
    reSize: function (exeIdm) {
        this.saveSize();
        var _this = this;
        if (exeIdm) {
            _this.setSize(exeIdm);
        } else {
            setTimeout(function () {
                _this.setSize(exeIdm);
            }, 10);
        }
    },
    appendTo: function (target) {
        var uuid = $B.generateDateUUID();
        this["id"] = uuid;
        this.table.appendTo(target).attr("id", uuid);
        var _this = this;
        setTimeout(function () {
            _this.reSize();
            var selection = _this.edit.getDomSelection();
            try {
                selection.removeAllRanges();
            } catch (e) { }
        }, 2);
        this.contenteditableTxt = this.table.parent();
        this.table.mouseleave(function () {
            _this.contenteditableTxt.removeAttr("contenteditable");
        });
    },
    _createTr: function (props, css) {
        var tr = $("<tr/>");
        if (props) {
            tr.attr(props);
        }
        if (css) {
            tr.css(css);
        }
        return tr;
    },
    _createTd: function (props, css) {
        var td = $("<td id='" + getUUID() + "' class='k_box_size'><p style='-webkit-margin-before: 0px;-webkit-margin-after: 0px;-webkit-margin-start: 0px;-webkit-margin-end: 0px;' id='" + getUUID() + "'><span style='" + eConfig.defaultStyle + "' id='" + getUUID() + "'>\u200B</span></p></td>");
        td.children("p").css(eConfig.pElementCss);
        if (props) {
            td.attr(props);
        }
        if (css) {
            td.css(css);
        }
        return td;
    },
    /**
     * l左侧插入列  
     * r右侧插入列
     * **/
    insertColFn: function (prs) {
        this.edit._onChange();
        //console.log("insertColFn insertColFn insertColFn-----> ");
        var index = parseInt(this.clickTd.attr("index"));
        var newTd,
            events = this._getTdEvents();
        if (prs === "r") {
            var sp = this.clickTd.attr("colspan");
            if (sp) {
                index = index + parseInt(sp) - 1;
            }
        }
        var colWidth = 80;
        var trs = this.tbody.children();
        var _this = this;
        trs.each(function () {
            var tr = $(this);
            tr.children().each(function () {
                var td = $(this);
                var idx = parseInt(td.attr("index"));
                var colspan = td.attr("colspan");
                var startCol = parseInt(td.attr("col"));
                var style = td.attr("style");
                var row = td.attr("row");
                var isFined, insertFn, nextIdx, endIdx;
                if (prs === "l") { //左边插入
                    insertFn = "insertAfter";
                    if (colspan) {
                        colspan = parseInt(colspan);
                        endIdx = idx + colspan;
                        nextIdx = endIdx;
                    } else {
                        nextIdx = idx + 1;
                    }
                    if (idx === index) {
                        insertFn = "insertBefore";
                        isFined = true;
                    } else if (nextIdx === index) {
                        isFined = true;
                    }
                    if (isFined) {
                        newTd = _this._createTd({
                            "tabindex": "0",
                            "row": row,
                            "col": startCol,
                            "index": nextIdx
                        }, eConfig.table.tdCss);
                        newTd.attr("style", style);
                        newTd.width(colWidth).height("auto");
                        newTd[insertFn](td).on(events);
                        if (insertFn === "insertAfter") {
                            startCol = startCol + 1;
                            newTd.attr({
                                "col": startCol,
                                "index": nextIdx
                            });
                        } else {
                            newTd.attr({
                                "col": idx,
                                "index": idx
                            });
                        }
                        return false;
                    } else {
                        if (colspan) {
                            if (index >= idx && index <= endIdx) {
                                td.attr("colspan", colspan + 1);
                                return false;
                            }
                        } else {
                            if (idx >= index) {
                                return false;
                            }
                        }
                    }
                } else { //右侧插入                        
                    insertFn = "insertAfter";
                    if (colspan) {
                        colspan = parseInt(colspan);
                        endIdx = idx + colspan;
                        isFined = (endIdx - 1) === index;
                    } else {
                        isFined = idx === index;
                    }
                    if (!isFined) {
                        if ((idx - 1) === index) {
                            insertFn = "insertBefore";
                            isFined = true;
                        } else if (td.next().length === 0) {
                            insertFn = "insertAfter";
                            isFined = true;
                        }
                    }
                    if (isFined) {
                        newTd = _this._createTd({
                            "tabindex": "0",
                            "row": row,
                            "col": 0,
                            "index": 0
                        }, eConfig.table.tdCss);
                        newTd.attr("style", style);
                        newTd.width(colWidth).height("auto");
                        newTd[insertFn](td).on(events);
                        if (insertFn === "insertAfter") {
                            startCol++;
                            newTd.attr({
                                "col": startCol,
                                "index": idx + 1
                            });
                        } else {
                            newTd.attr({
                                "col": startCol,
                                "index": idx
                            });
                        }
                        return false;
                    } else {
                        if (colspan) {
                            if (index >= idx && index < endIdx) {
                                td.attr("colspan", colspan + 1);
                                return false;
                            }
                        } else {
                            if (idx >= index) {
                                return false;
                            }
                        }
                    }
                }
            });
        });
        this.resetTableIndex();
        this.reSize(true);
        this.edit.moveToEnd(newTd);
    },
    /**
     * t上方插入行
     * b下方插入行
     * ***/
    insertRowFn: function (prs) {
        this.edit._onChange();
        var currentRow = this.clickTd.parent();
        var rowIdx = parseInt(this.clickTd.attr("row"));
        var _this = this;
        var newTr = this._createTr({
            "id": "row_0"
        });
        var newTd, i, j, len;
        if (prs === "t") { //上方插入
            newTr.attr("id", "row_" + rowIdx);
            newTr.insertBefore(currentRow);
        } else {
            var rowspan = this.clickTd.attr("rowspan");
            if (rowspan) {
                rowspan = parseInt(rowspan) - 1;
                while (rowspan > 0) {
                    currentRow = currentRow.next();
                    rowspan--;
                }
                rowIdx = parseInt(currentRow.attr("id").replace("row_", ""));
            }
            rowIdx++;
            newTr.attr("id", "row_" + rowIdx);
            newTr.insertAfter(currentRow);
        }
        var currentRowIndex = rowIdx;
        /***更新后面的id行号***/
        var nextRow = newTr.next();
        while (nextRow.length > 0) {
            rowIdx++;
            nextRow.attr("id", "row_" + rowIdx);
            nextRow.children().attr("row", rowIdx);
            nextRow = nextRow.next();
        }
        //分析需要插入多少个td,提前需要rowspan+1的单元格
        var prevRow = newTr.prev();
        var rowspanTds = [];
        var notCreateTd = {};
        var td, rspan;
        while (prevRow.length > 0) {
            var ridx = parseInt(prevRow.attr("id").replace("row_", ""));
            var childs = prevRow.children();
            for (i = 0, len = childs.length; i < len; ++i) {
                td = $(childs[i]);
                var tdIdx = parseInt(td.attr("index"));
                if (!notCreateTd[tdIdx]) {
                    rspan = td.attr("rowspan");
                    if (rspan) {
                        rspan = parseInt(rspan) - 1;
                        var tmp = ridx + rspan;
                        if (tmp >= currentRowIndex) {
                            notCreateTd[tdIdx] = true;
                            var colspan = td.attr("colspan");
                            if (colspan) {
                                colspan = parseInt(colspan) - 1;
                                while (colspan > 0) {
                                    tdIdx++;
                                    notCreateTd[tdIdx] = true;
                                    colspan--;
                                }
                            }
                            rowspanTds.push(td);
                        }
                    }
                }
            }
            prevRow = prevRow.prev();
        }
        var startIndex = 0;
        var colIdx = 0;
        var style = this.clickTd.attr("style");
        var events = this._getTdEvents();
        while (startIndex < this.colNum) {
            if (!notCreateTd[startIndex]) {
                newTd = _this._createTd({
                    "tabindex": "0",
                    "row": currentRowIndex,
                    "col": colIdx,
                    "index": startIndex
                }, eConfig.table.tdCss);
                newTd.attr("style", style);
                newTd.width("auto").height("auto").on(events);
                newTd.appendTo(newTr);
                colIdx++;
            }
            startIndex++;
        }
        for (j = 0, len = rowspanTds.length; j < len; ++j) {
            td = rowspanTds[j];
            rspan = parseInt(td.attr("rowspan")) + 1;
            td.attr("rowspan", rspan);
        }
        this.reSize(true);
        this.rowNum++;
        if (newTd) {
            this.edit.moveToEnd(newTd);
        }
    },
    /**删除内容**/
    deleteContentFn: function (prs) {
        this.edit._onChange();
        var activeTd;
        this.foreachSeletedTds(function (rec) {
            var td = rec.td;
            td.find("a").remove();
            activeTd = td.html("\u200B");
        });
        this.clearSelected();
        this.edit.moveToEnd(activeTd);
        this.setClickTd(activeTd);
    },
    insertImageFn: function () {
        this.edit._onChange();
        this.edit.openInsertImageWindow("picture", {
            undo: true,
            needRange: false
        });
    },
    insertFileFn: function () {
        this.edit._onChange();
        this.edit.openInsertFileWindow("upload", {
            undo: true,
            needRange: false
        });
    },
    deleteRowFn: function (prs) {
        this.edit._onChange();
        var deleteRow = {};
        var _this = this;
        var hasLoop = this.foreachSeletedTds(function (rec) {
            var r = parseInt(rec.td.attr("row"));
            var row = rec.td.parent();
            deleteRow[r] = row;
            var rspan = rec.td.attr("rowspan");
            if (rspan) {
                var curRow = row;
                rspan = parseInt(rspan) - 1;
                while (rspan > 0) {
                    r++;
                    deleteRow[r] = curRow.next();
                    curRow = deleteRow[r];
                    rspan--;
                }
            }
        });
        if (hasLoop) {
            var delKeys = Object.keys(deleteRow);
            if (delKeys.length === _this.rowNum) {
                _this.deleteTableFn();
            } else {
                delKeys.forEach(function (key) {
                    var row = deleteRow[key];
                    _this._removeRow(row);
                });
                _this._activedFirstTd();
            }
        } else {
            var delRow = this.clickTd.parent();
            if (_this.rowNum === 1) {
                _this.deleteTableFn();
            } else {
                _this._removeRow(delRow);
                _this._activedFirstTd();
            }
        }
    },
    _removeRow: function (row) {
        var curRowIndex = parseInt(row.attr("id").replace("row_", ""));
        var prevRow = row.prev();
        var rowSpanTdArray = [];
        var childs, i, len, td, h;
        var _this = this;
        while (prevRow.length > 0) {
            childs = prevRow.children();
            for (i = 0, len = childs.length; i < len; ++i) {
                td = $(childs[i]);
                var index = parseInt(td.attr("index"));
                var rowspan = td.attr("rowspan");
                var rowIdx = parseInt(td.attr("row"));
                if (rowspan) {
                    var rIdx = parseInt(rowspan) - 1 + rowIdx;
                    if (rIdx >= curRowIndex) {
                        rowSpanTdArray.push(td);
                    }
                }
            }
            prevRow = prevRow.prev();
        }
        var newTdRec = [];
        row.children().each(function (i) {
            td = $(this);
            var rowspan = td.attr("rowspan");
            if (rowspan) {
                var style = td.attr("style");
                newTdRec.push({
                    style: style,
                    content: td.html(),
                    height: td.data("height"),
                    index: parseInt(td.attr("index")),
                    rowspan: parseInt(rowspan),
                    colspan: td.attr("colspan")
                });
            }
        });
        var removeHeight = row.height();
        var nextRow = row.next();
        row.remove();
        for (i = 0, len = rowSpanTdArray.length; i < len; ++i) {
            td = rowSpanTdArray[i];
            h = td.data("height") - removeHeight;
            var rs = parseInt(td.attr("rowspan")) - 1;
            if (rs > 1) {
                td.attr("rowspan", rs);
            } else {
                td.removeAttr("rowspan");
            }
            td.innerHeight(h);
        }
        var events;
        len = newTdRec.length;
        if (len > 0) {
            events = this._getTdEvents();
        }
        for (i = 0; i < len; ++i) {
            var rec = newTdRec[i];
            td = _this._createTd({
                "tabindex": "0",
                "row": 0,
                "col": 0,
                "index": rec.index
            }, eConfig.table.tdCss);
            td.children("p").html(rec.content);
            td.attr("style", rec.style).attr("index", rec.index);
            var rspan = rec.rowspan - 1;
            if (rspan > 1) {
                td.attr("rowspan", rspan);
            }
            if (rec.colspan) {
                td.attr("colspan", rec.colspan);
            }
            h = rec.height - removeHeight;
            td.innerHeight(h).data("height", h).on(events);
            var idx = rec.index;
            if (idx === 0) {
                td.prependTo(nextRow);
            } else {
                idx = idx - 1;
                var childrens = nextRow.children();
                for (var k = 0, klen = childrens.length; k < klen; ++k) {
                    var targetTd = $(childrens[k]);
                    var _index = parseInt(targetTd.attr("index"));
                    if (idx === _index) {
                        td.insertAfter(targetTd);
                        break;
                    } else if (_index > idx) {
                        var prevTd = targetTd.prev();
                        if (prevTd.length > 0) {
                            td.insertAfter(prevTd);
                            break;
                        } else {
                            td.insertBefore(targetTd);
                            break;
                        }
                    } else {
                        var nextTd = targetTd.next();
                        if (nextTd.length === 0) {
                            td.insertAfter(targetTd);
                        }
                    }
                }
            }
        }
        this.reSize(true);
        this.rowNum--;
    },
    deleteColFn: function () {
        this.edit._onChange();
        var _this = this;
        var deleteColMap = {};
        var deleteColArray = [];
        var hasLoop = this.foreachSeletedTds(function (rec) {
            var col = parseInt(rec.td.attr("index"));
            if (!deleteColMap[col]) {
                deleteColMap[col] = true;
                deleteColArray.push(col);
                var colspan = rec.td.attr("colspan");
                if (colspan) {
                    colspan = parseInt(colspan) - 1;
                    while (colspan > 0) {
                        col++;
                        if (!deleteColMap[col]) {
                            deleteColMap[col] = true;
                            deleteColArray.push(col);
                        }
                        colspan--;
                    }
                }
            }
        });
        if (hasLoop) {
            if (deleteColArray.length === this.colNum) {
                _this.deleteTableFn();
            } else {
                for (var i = 0, len = deleteColArray.length; i < len; ++i) {
                    var rmTd = deleteColArray[i];
                    _this._removeCol(rmTd);
                }
                _this._activedFirstTd();
            }
        } else {
            if (_this.colNum === 1) {
                _this.deleteTableFn();
            } else {
                var col = parseInt(_this.clickTd.attr("index"));
                _this._removeCol(col);
                _this._activedFirstTd();
            }
        }
    },
    _activedFirstTd: function () {
        var activeTd = this.tbody.children().first().children().first();
        this.edit.moveToEnd(activeTd);
        this.mutilSelectBackground = {};
        this.selectTdArray = [activeTd];
    },
    _removeCol: function (colIdx) {
        var _resetIndexFn = function (nextTd) {
            while (nextTd.length > 0) {
                var index = parseInt(nextTd.attr("index")) - 1;
                nextTd.attr("index", index);
                nextTd = nextTd.next();
            }
        };
        var resetIndexTds = [];
        var trs = this.tbody.children();
        trs.each(function () {
            var tr = $(this);
            tr.children().each(function () {
                var td = $(this);
                var idx = parseInt(td.attr("index"));
                var endIdx = idx;
                var colspan = td.attr("colspan");
                if (colspan) {
                    colspan = parseInt(colspan);
                    var newSpan;
                    endIdx = idx + colspan - 1;
                    if (idx === colIdx) {
                        newSpan = colspan - 1;
                    } else if (endIdx === colIdx) {
                        newSpan = colspan - 1;
                    } else if (idx < colIdx && idx < endIdx) {
                        newSpan = colspan - 1;
                    }
                    if (newSpan) {
                        if (newSpan === 1) {
                            td.removeAttr("colspan");
                            resetIndexTds.push(td.next());
                            return false;
                        } else {
                            td.attr("colspan", newSpan);
                            resetIndexTds.push(td.next());
                            return false;
                        }
                    }
                } else {
                    if (idx === colIdx) {
                        resetIndexTds.push(td.next());
                        td.remove();
                        return false;
                    } else if (endIdx >= colIdx) {
                        resetIndexTds.push(td);
                        return false;
                    }
                }
            });
        });
        for (var i = 0, len = resetIndexTds.length; i < len; ++i) {
            _resetIndexFn(resetIndexTds[i]);
        }
        this.reSize(true);
        this.colNum--;
    },
    deleteTableFn: function () {
        if(this.edit.movingAcn){
            this.edit.movingAcn.hide();
        } 
        this.edit._onChange();
        var p = this.table.parent();
        var edit = this.edit;
        var tableId = this.table.attr("id");
        edit._deleteTable(tableId);
        p.html("<span style='" + eConfig.defaultStyle + "' id='" + tableId + "'>\u200B</span>");
        edit.createCrossRange(p, p);
        edit.moveToEnd(p);
    },
    mergeFn: function () {
        var rowspan = 0,
            colspan = 0,
            helper = 0,
            modifyTd,
            rowRec = {},
            colRec = {},
            _this = this;
        this.edit._onChange();
        this.edit._putUndo();
        this.foreachSeletedTds(function (rec) {
            var td = rec["td"];
            var row = parseInt(td.attr("row"));
            var col = parseInt(td.attr("index"));
            rowRec[row] = 1;
            colRec[col] = 1;
            rowspan = td.attr("rowspan");
            colspan = td.attr("colspan");
            var rspan = 0,
                clspan = 0;
            if (rowspan) {
                rspan = parseInt(rowspan) - 1;
                while (rspan > 0) {
                    row = ++row;
                    rowRec[row] = 1;
                    rspan = --rspan;
                }
            }
            if (colspan) {
                clspan = parseInt(colspan) - 1;
                while (clspan > 0) {
                    col = ++col;
                    colRec[col] = 1;
                    clspan = --clspan;
                }
            }
            if (helper === 0) {
                modifyTd = td;
            }
            helper = ++helper;
        });
        rowspan = Object.keys(rowRec).length;
        colspan = Object.keys(colRec).length;
        helper = 0;
        var w = 0;
        var heightRec = {};
        var widthRec = {};
        var removeTdArray = [];
        var keys;
        _this.foreachSeletedTds(function (rec) {
            var td = rec["td"];
            var col = td.attr("index");
            var row = td.attr("row");
            if (widthRec[row]) {
                widthRec[row] = widthRec[row] + td.outerWidth();
            } else {
                widthRec[row] = td.innerWidth();
            }
            if (heightRec[col]) {
                heightRec[col] = heightRec[col] + td.outerHeight();
            } else {
                heightRec[col] = td.innerHeight();
            }
            if (helper !== 0) {
                removeTdArray.push(td);
            }
            helper = ++helper;
        });
        for (var i = 0, len = removeTdArray.length; i < len; ++i) {
            removeTdArray[i].remove();
        }
        if (rowspan > 1) {
            keys = Object.keys(heightRec);
            modifyTd.attr("rowspan", rowspan).data("height", heightRec[keys[0]]);
        }
        if (colspan > 1) {
            keys = Object.keys(widthRec);
            modifyTd.attr("colspan", colspan).data("width", widthRec[keys[0]]);
        }
        this.setSize();
        //清空选择
        this.clearSelected();
        this.edit.moveToEnd(modifyTd);
    },
    splitFn: function () {
        this.edit._onChange();
        var _this = this;
        var colspan = _this.clickTd.attr("colspan");
        var rowCount = parseInt(_this.clickTd.attr("rowspan")) - 1;
        var idx = parseInt(_this.clickTd.attr("index"));
        var currentIdx = idx;
        //var row = this.clickTd.attr("row");
        var copyStyle = _this.edit._style2CssObject(this.clickTd, true);
        delete copyStyle.width;
        delete copyStyle.height;
        var events = this._getTdEvents();
        var avgWidth, count, td, i, len;
        if (colspan) {
            colspan = parseInt(colspan);
            avgWidth = _this.clickTd.data("width") / colspan;
            _this.clickTd.width(avgWidth).removeAttr("colspan");
            count = colspan - 1;
            var insertTarget = _this.clickTd;
            while (count > 0) {
                idx = idx + 1;
                td = this._createTd({
                    "tabindex": "0",
                    "row": 0,
                    "col": 0,
                    "index": idx
                }, eConfig.table.tdCss);
                count = --count;
                td.on(events).css($.extend(copyStyle, {
                    "width": avgWidth,
                    "height": "auto"
                }));
                insertTarget = td.insertAfter(insertTarget);
            }
        }
        if (rowCount) {
            var tdCount = 1; //需要创建的td数量
            if (colspan) {
                tdCount = colspan;
            }
            if (!avgWidth) {
                avgWidth = _this.clickTd.data("width") / colspan;
            }
            _this.clickTd.width(avgWidth).height("auto").removeAttr("rowspan");
            var tdRow = this.clickTd.parent();
            var currentRow = tdRow.next();
            var nextIdx = 0;
            var cFn = function () {
                td = _this._createTd({
                    "tabindex": "0",
                    "row": 0,
                    "col": 0,
                    "index": nextIdx
                }, eConfig.table.tdCss);
                td.on(events);
                nextIdx++;
                currentRow.append(td);
            };
            var targetTd, childArray, index, fined, tr, helper;
            while (rowCount > 0) {
                childArray = currentRow.children();
                len = childArray.length;
                if (len === 0) {
                    tdRow.children().each(cFn);
                } else {
                    for (i = 0; i < len; ++i) {
                        td = $(childArray[i]);
                        index = parseInt(td.attr("index"));
                        targetTd = undefined;
                        if (index >= idx) {
                            targetTd = td.prev();
                        } else if (td.next().length === 0) {
                            targetTd = td;
                        }
                        if (targetTd) {
                            fined = targetTd.length > 0;
                            tr = td.parent();
                            helper = 0;
                            count = tdCount;
                            nextIdx = currentIdx;
                            while (count > 0) {
                                if (fined) {
                                    td = _this._createTd({
                                        "tabindex": "0",
                                        "row": 0,
                                        "col": 0,
                                        "index": nextIdx
                                    }, eConfig.table.tdCss);
                                    targetTd = td.insertAfter(targetTd);
                                    targetTd.on(events).css($.extend(copyStyle, {
                                        "width": avgWidth,
                                        "height": "auto"
                                    }));
                                    nextIdx = nextIdx + 1;
                                } else { //第一列利用tr插入td
                                    td = _this._createTd({
                                        "tabindex": "0",
                                        "row": 0,
                                        "col": 0,
                                        "index": helper
                                    }, eConfig.table.tdCss.td);
                                    if (helper === 0) { //先tr preppend ，后target insertAfter
                                        td.on(events).css($.extend(copyStyle, {
                                            "width": avgWidth,
                                            "height": "auto"
                                        }));
                                        tr.prepend(td);
                                        targetTd = td;
                                    } else {
                                        targetTd = td.insertAfter(targetTd).on(events).css($.extend(copyStyle, {
                                            "width": avgWidth,
                                            "height": "auto"
                                        }));
                                    }
                                    helper = ++helper;
                                }
                                count = --count;
                            }
                            break;
                        }
                    }
                }
                currentRow = currentRow.next();
                rowCount = --rowCount;
            }
        }
        _this.edit.moveToEnd(this.clickTd);
        setTimeout(function () {
            _this.saveSize();
        }, 2);
    },
    remove: function () {    
        var i,len;
        if(this.$splitLine){
            this.$splitLine.remove();            
        }   
        if(this.$anchor){
            this.$anchor.hide();
        }
        if(this.$addBtn){
            this.$addBtn.hide();
        }
        this.jqObj.removeData("object"); 
        this.table.remove();
        this.destroy();
    },
    destroy: function () {
        for (var p in this) {
            if (this.hasOwnProperty(p)) {
                delete this[p];
            }
        }
    }
};
/**
 * 表格属性    
 * **/
function TableProps(edit) {
    $B.extend(this, TableProps); //继承父类 
    this.edit = edit;
    this.wrap = $("<div style='position: absolute;z-index: 99999999;display:none;background:#ffffff;padding:5px 6px;width:190px;border: 1px solid #E0E0E0;' class='k_box_shadow'></div>");
    this.jqObj = this.wrap;
    var form = $(eConfig.tablePropsForm);
    this.wrap.append(form);
    window["_TableProps_"] = this;
    this.target = undefined;
    this.wrap.appendTo(_getBody());
    var _this = this;
    form.find("._color_picker").click(function () {
        var $t = $(this);
        _this.color.show($t);
        return false;
    });
    this.color = new $B.ColorPicker(undefined, {
        update2Target: false,
        showCaret: false,
        positionFix: {
            top: 2,
            left: 1
        },
        change: function (val) {
            if (_this.target.selectBackground === val) {
                var tmp = [];
                for (var i = 0, len = val.length; i < len - 1; ++i) {
                    tmp.push(val[i]);
                }
                val = tmp.join() + "1";
            }
            this.css("background-color", val);
            if (this.attr("id") === "_border_color_picker") {
                _this.onChange();
            } else {
                _this.onChange(val);
            }
        }
    }).setValue("#A9CADD");
    this.color["name"] = "TableProps ColorPicker";
    form.find(".k_edit_border_wrap").children().click(function () {
        var seft = $(this);
        seft.addClass("activtd").siblings().removeClass("activtd");
        _this.onChange();
    });
    this.borderSize = form.find("#_border_size_opts_").on("change", function () {
        _this.onChange();
    });
    this.borderStyle = form.find("#_border_style_opts_").on("change", function () {
        _this.onChange();
    });
    form.find("#_split_merge_td_").children().click(function () {
        var $t = $(this).find("a");
        var callFn = $t.data("flag");
        if (_this.target[callFn]) {
            _this._makeUndoData();
            _this.target[callFn]();
        }
        _this.hide();
    });
    this.borderColor = $("#_border_color_picker");
    // this.backgroundColor = $("#_background_color_picker");
    this.jqObj = this.wrap;
    var tbody = form.children("tbody").children().on({
        mouseover: function () {
            var tr = $(this);
            if (tr.hasClass("_delete_op_tr")) {
                _this.showDeleteMenu(tr);
            } else if (tr.hasClass("_insert_op_tr")) {
                _this.showInsertMenu(tr);
            } else {
                _this.hideDeleteMenu();
                _this.hideInsertMenu();
            }
        }
    });
    this.wrap.click(function () {
        _this.color.hide();
    });
    var setting = this.wrap.find("._section_set_tr");
    setting.find("td").children("div").html("<i style='padding-right:20px;font-size:16px;' class='fa fa-exchange'></i>" + eConfig.label.setSectionWidth);
    setting.click(function () {
        var p = _this.target.jqObj.parent();
        while (p.length > 0) {
            if (p[0].tagName === "DIV") {
                break;
            }
            p = p.parent();
        }
        _this.edit.startPElement = p;
        _this.edit.endPElement = p;
        _this.edit.setSectionWidth();
        _this.hide();
    });
    this.resetSectionTr = this.wrap.find("._rection_reset_tr");
    this.resetSectionTr.find("td").children("div").html("<i style='padding-right:20px;font-size:16px;' class='fa fa-resize-horizontal'></i>" + eConfig.label.resetSectionWidth);
    this.resetSectionTr.click(function () {
        var p = _this.target.jqObj.parent();
        while (p.length > 0) {
            if (p[0].tagName === "DIV") {
                break;
            }
            p = p.parent();
        }
        _this.edit.startPElement = p;
        _this.edit.endPElement = p;
        _this.edit.resetSectionWidth();
        _this.hide();
    });
    this.wrap.mousedown(function () {
        stopDefaultctxMenu();
    });
    this.wrap.find("._rection_move_tr").click(function () {
        var p = _this.target.jqObj.parent();
        while (p.length > 0) {
            if (p[0].tagName === "DIV") {
                break;
            }
            p = p.parent();
        }
        var eles = [p];
        _this.edit._setMovingTargets(eles, false);
        _this.hide();
    });
}
TableProps.prototype = {
    constructor: TableProps,
    showInsertMenu: function (tr) {
        this.hideDeleteMenu();
        var ofs = tr.offset();
        var w = this.wrap.outerWidth();
        ofs.left = this.wrap.offset().left + w;
        var body = _getBody();
        var bodyHeight = body.height();
        if ((bodyHeight - ofs.top) < 160) {
            ofs.top = ofs.top - 138;
        }
        if (!this["insertMenu"]) {
            var _this = this; // 
            var wrap = $("<div style='position: absolute;z-index:99999999;background:#ffffff;padding:2px 3px;width:80px;' class='k_box_shadow k_edit_delete_op_wrap'></div>");
            $("<span>" + eConfig.table.insertRight + "</span>").appendTo(wrap).on("click", function () {
                _this.operatorFn("insertColFn", "r");
            });
            $("<span>" + eConfig.table.insertLeft + "</span>").appendTo(wrap).on("click", function () {
                _this.operatorFn("insertColFn", "l");
            });
            $("<span>" + eConfig.table.insertUp + "</span>").appendTo(wrap).on("click", function () {
                _this.operatorFn("insertRowFn", "t");
            });
            $("<span>" + eConfig.table.insertDown + "</span>").appendTo(wrap).on("click", function () {
                _this.operatorFn("insertRowFn", "d");
            });
            $("<span>" + eConfig.table.insertFile + "</span>").appendTo(wrap).on("click", function () {
                _this.operatorFn("insertFileFn");
            });
            $("<span>" + eConfig.table.insertImg + "</span>").appendTo(wrap).on("click", function () {
                _this.operatorFn("insertImageFn");
            });
            this["insertMenu"] = wrap.css(ofs).appendTo(body);
        } else {
            this["insertMenu"].css(ofs).show();
        }
    },
    hideInsertMenu: function (tr) {
        if (this["insertMenu"]) {
            this["insertMenu"].hide();
        }
    },
    showDeleteMenu: function (tr) {
        this.hideInsertMenu();
        var ofs = tr.offset();
        var w = this.wrap.outerWidth();
        ofs.left = this.wrap.offset().left + w;
        var body = _getBody();
        var bodyHeight = body.height();
        if ((bodyHeight - ofs.top) < 105) {
            ofs.top = ofs.top - 82;
        }
        if (!this["deleteMenu"]) {
            var _this = this;
            var wrap = $("<div style='position: absolute;z-index:99999999;background:#ffffff;padding:2px 3px;width:80px;' class='k_box_shadow k_edit_delete_op_wrap'></div>");
            $("<span>" + eConfig.table.removeContent + "</span>").appendTo(wrap).on("click", function () {
                _this.operatorFn("deleteContentFn");
            });
            $("<span>" + eConfig.table.removeRow + "</span>").appendTo(wrap).on("click", function () {
                _this.operatorFn("deleteRowFn");
            });
            $("<span>" + eConfig.table.removeCol + "</span>").appendTo(wrap).on("click", function () {
                _this.operatorFn("deleteColFn");
            });
            $("<span>" + eConfig.table.removeTable + "</span>").appendTo(wrap).on("click", function () {
                _this.operatorFn("deleteTableFn");               
            });
            this["deleteMenu"] = wrap.css(ofs).appendTo(_getBody());
        } else {
            this["deleteMenu"].css(ofs).show();
        }
    },
    //undo记录
    _makeUndoData: function () {
        this.target.edit.putUndoByFocus();
    },
    operatorFn: function (opFn, prs) {
        this.hide();
        if (typeof this.target[opFn] === "function") {
            this._makeUndoData();
            this.target[opFn](prs);
        }
    },
    hideDeleteMenu: function () {
        if (this["deleteMenu"]) {
            this["deleteMenu"].hide();
        }
    },
    onChange: function (backgroundColor) {
        var _tg = this.jqObj.find("input[type=radio]:checked").val();
        var border = this.jqObj.find(".k_edit_border_wrap").children(".activtd").attr("tg");
        var size = this.borderSize.val();
        var style = this.borderStyle.val();
        var borderColor = this.borderColor.css("background-color");
        var css = {};
        if (backgroundColor) {
            css["background-color"] = backgroundColor;
        }
        var val = size + "px " + style + " " + borderColor;
        if (border === "border") {
            css["border-left"] = val;
            css["border-top"] = val;
            css["border-right"] = val;
            css["border-bottom"] = val;
        } else {
            css[border] = val;
        }
        var params = {
            "target": _tg,
            "css": css
        };
        if (typeof this.target.cssSubscribe === "function") {
            this.target.cssSubscribe(params);
        }
    },
    hide: function () {
        //console.log("table hide >>>>>>>>>>>>>>>>>>>>>");
        this.wrap.hide();
        this.color.hide();
        this.hideDeleteMenu();
        this.hideInsertMenu();
        return this;
    },
    show: function (ofs) {
        this.hideDeleteMenu();
        this.hideInsertMenu();
        var bodyWidth = _getBody().width();
        var endPosX = ofs.left + 220;
        var diff = endPosX - bodyWidth;
        if (diff > 0) {
            ofs.left = ofs.left - diff;
        }
        this.wrap.css(ofs).show();
        this.color.hide();
        this._showOrHideOpt();
        return this;
    },
    setTarget: function (target) {
        this.target = target;
        this._showOrHideOpt();
        return this;
    },
    _showOrHideOpt: function () {
        if (this.target && this.target.jqObj) {
            var pleft = this.target.jqObj.parent().css("padding-left");
            if (pleft !== "0px") {
                this.resetSectionTr.show();
            } else {
                this.resetSectionTr.hide();
            }
        }
    }
};
window["TableProps"] = TableProps;
/***
 * 根据undo/redoc的记录创建一个内容被替换前的记录
 * ***/
Kedit.prototype.makeUndoRedoDataByRec = function (rec) {
    var nextRec;
    if(rec.isFloat){//浮动面板记录
        nextRec = {
            isFloat: true,    
            rebuild: !rec.rebuild,   
            id: rec.id, 
            html: rec.html
        };
        return nextRec;
    }
    nextRec = {
        isClear:rec.isClear,
        startRegionId: rec.startRegionId,
        endRegionId: rec.endRegionId,
        rangeOfs: rec.rangeOfs,
        replaceSectionId: [],
        html: [],
        inputId: rec.inputId,
        prevSectionId: rec.prevSectionId,
        nextSectionId: rec.nextSectionId
    };
    if (rec["isClear"]) {//如果是清空
        //this.$fixInput.trigger("mousedown");
        //this.moveToEnd(this.$fixInput.children().first());
        this._makeClearRec(nextRec);
    } else {//非清空操作
        var $input = this.$fixInput;
        if (rec.inputId) {
            $input = this.$inputWrap.children("div.k_edit_float_panel").find("#" + rec.inputId);
        }
        var p, id;
        for (var i = 0, len = rec.replaceSectionId.length; i < len; ++i) {
            id = rec.replaceSectionId[i];
            p = $input.find("#" + id);
            nextRec.replaceSectionId.push(id);//删除场景下，id对应的段落不一定存在
            if (p.length > 0) {
                
                nextRec.html.push(p[0].outerHTML);
            }
        }
    }
    return nextRec;
};

/**
 * 撤销操作
 * ***/
Kedit.prototype.undo = function (params, btn) {
    var rec = this.undoStack.pop();
    var _this = this;
    try {
        //console.log("execute undo >>>>>>>>>>>>>>>>>>>>>>>>>");
        //创建一个redo记录
        var nextRec = this.makeUndoRedoDataByRec(rec);
        var $input = this.$input;
        if (rec.inputId) {
            $input = this.$inputWrap.children("div.k_edit_float_panel").find("#" + rec.inputId);
            if ($input.length === 0) {
                return;
            }
        }
        this._recoverySectionContent(rec);
        this._putRedo(nextRec); //压入redo栈
    } catch (ex) {
        console.log("undo exception ");
    }
    if (this.undoStack.length === 0) {
        btn.addClass("k_edit_tools_disabled");
    }
};

/**
 *重做操作 
**/
Kedit.prototype.redo = function (params, btn) {
    var rec = this.redoStack.pop();
    //console.log("redo >>>>>>>>>>>>>> execute>>>>");
    try {
        //创建一个undo记录
        var nextRec = this.makeUndoRedoDataByRec(rec);
        var $input = this.$input;
        if (rec.inputId) {
            $input = this.$inputWrap.children("div.k_edit_float_panel").find("#" + rec.inputId);
            if ($input.length === 0) {
                return;
            }
        }
        this._recoverySectionContent(rec);
        this._putUndoNotClearRedo(nextRec); //压入undo栈
    } catch (ex) {
        console.log("redo exception");
    }
    if (this.redoStack.length === 0) {
        btn.addClass("k_edit_tools_disabled");
    }
};
/**
 * 撤销重做恢复 浮动面板里面的事件 
 * *****/
Kedit.prototype._recoveryFloatPanelEvents = function($fp){
    //console.log("recoveryFloatPanelEvents >>>> ");
    var inputWrap = this._bindFloatPanelEvents($fp);
    if (inputWrap) {
        var pres = inputWrap.children("div");
        this.buildObjectsEventsByTag(pres);
        var videoPreArray = [];
        pres.children("pre").each(function () {
            var $pre = $(this);
            if ($pre.hasClass("k_video_pre")) {
                videoPreArray.push($pre);
            }
        });
        var videoPre, videoOpt;
        for (var i = 0, len = videoPreArray.length; i < len; ++i) {
            videoPre = videoPreArray[i];
            videoOpt = JSON.parse(videoPre.attr("data").replace(/&quot;/g, "\""));
            this._createVideoPlayer(videoPre, videoOpt);
        }
        videoPreArray = undefined;
    }
}; 
/**
 *恢复undo\redo内容
* ***/
Kedit.prototype._recoverySectionContent = function (rec) {
   if(rec.isFloat) {
        if(rec.rebuild){//恢复面板
            var $fp = $(rec.html).appendTo(this.$inputWrap);
            this._recoveryFloatPanelEvents($fp);
        }else{//删除面板
            this.$inputWrap.children("#"+rec.id).remove();
            if (this.floatTools) {
                this.floatTools.hide();
            }
            if (this.floatPropPanel) {
                this.floatPropPanel.hide();
            }
        } 
        return;
    }
    var repalceIds = rec["replaceSectionId"];
    var firstRecoverSection;
    var recovertyHtml = rec["html"];
    var firstAndLastNewSection = [];
    var _this = this;
    var i, len, id, rmSection, $p, $input = this.$input;
    if (rec.inputId) {
        $input = this.$inputWrap.children("div.k_edit_float_panel").find("#" + rec.inputId);
    }
    //先移除需要替换的段落，移除时候插入第一个段落，其他待恢复的段落均插入这个新的第一个段落
    for (i = 0, len = repalceIds.length; i < len; ++i) {
        id = repalceIds[i];
        rmSection = $input.children("#" + id);
        if (!firstRecoverSection && rmSection.length > 0 && recovertyHtml.length > 0) {
            firstRecoverSection = $(recovertyHtml[0]).insertAfter(rmSection);
        }
        if (rmSection.length > 0) {
            this._removeSection(rmSection);
        }
    }
    if (firstRecoverSection) {//已经恢复了第一个段落，继续恢复其他段落
        this.buildObjectsEventsByTag(firstRecoverSection);
        firstAndLastNewSection.push(firstRecoverSection);
        if (recovertyHtml.length === 1) {
            firstAndLastNewSection.push(firstRecoverSection);
        }
        if(rec.isClear){//清空场景
            var $allPanel = this.$inputWrap.children(".k_edit_float_panel").each(function(){
                var $w = $(this);
                $w.children(".k_editor_float_input").children().each(function(){
                    _this._removeSection($(this));
                });
            });
            $allPanel.remove();
            firstRecoverSection.nextAll().each(function(){
                _this._removeSection($(this));
            });
        }
        //恢复其他段落内容
        var targetSection = firstRecoverSection;
        for (i = 1, len = recovertyHtml.length; i < len; ++i) {
            $p = $(recovertyHtml[i]);
            $p.insertAfter(targetSection);
            this.buildObjectsEventsByTag($p);
            targetSection = $p;
            if (i === len - 1) {
                firstAndLastNewSection.push(targetSection);
            }
        }      
    } else {//全删除场景，当前input中找不到rec["replaceSectionId"]对应的dom，则依赖 prevSectionId,nextSectionId进行恢复
        if (rec["prevSectionId"]) {
            var prevPel = $input.children("#" + rec["prevSectionId"]);
            for (i = 0, len = recovertyHtml.length; i < len; ++i) {
                $p = $(recovertyHtml[i]);
                $p.insertAfter(prevPel);
                this.buildObjectsEventsByTag($p);
                prevPel = $p;
                if (i === 0) {
                    firstAndLastNewSection.push(prevPel);
                }
                if (i === len - 1) {
                    firstAndLastNewSection.push(prevPel);
                }
            }
        } else if (rec["nextSectionId"]) {
            var nextPel = $input.children("#" + rec["nextSectionId"]);
            for (i = 0, len = recovertyHtml.length; i < len; ++i) {
                $p = $(recovertyHtml[i]);
                $p.insertBefore(nextPel);
                this.buildObjectsEventsByTag($p);
                if (i === 0) {
                    firstAndLastNewSection.push($p);
                }
                if (i === len - 1) {
                    firstAndLastNewSection.push($p);
                }
            }
        }
    }
    if (rec["floatItems"]) {
        var $t;
        len = rec["floatItems"].length;
        if (len > 0) {
            for (i = 0; i < len; ++i) {
                $t = $(rec["floatItems"][i]).appendTo(this.$inputWrap);
                this._recoveryFloatPanelEvents($t);
            }
        } else {
            this.$inputWrap.children(".k_edit_float_panel").remove();
        }
    }
    try{
        this._rebulidUndoRedoRange(rec, firstAndLastNewSection);
    }catch(e1){
        console.log("_rebulidUndoRedoRange exception  ");
    }   
    return firstAndLastNewSection;
};

/**undo redo后重建选区**/
Kedit.prototype._rebulidUndoRedoRange = function (rec, newSections) {
    //console.log("_rebulidUndoRedoRange >>>>>>>> _rebulidUndoRedoRange");    
    if (!rec["startRegionId"] || !rec.rangeOfs || $.isEmptyObject(rec.rangeOfs)) {
        //不需要恢复选区
        return;
    }
    var rangeOfs = rec.rangeOfs;
    var startId = rec["startRegionId"];
    var endId = rec["endRegionId"];
    var startSection,
        endSection,
        firstChild,
        endChild;
    var $input = this.$input;
    if (rec.inputId) {
        $input = this.$inputWrap.children("div.k_edit_float_panel").find("#" + rec.inputId);
    }
    if (rec["isClear"]) {//清空操作,恢复第一行为光标行
        if(!$.isEmptyObject(rangeOfs) && startId && endId){
            var allChild = $input.children();
            firstChild = allChild.find("#" + startId);
            endChild = allChild.find("#" + endId);
            if(firstChild.length > 0 && endChild.length > 0){
                firstChild = firstChild[0].firstChild;
                endChild = endChild[0].lastChild;
                this.setCrossRange(firstChild, endChild, rangeOfs.startOffset, rangeOfs.endOffset);
            }else{
                this.moveToEnd($input.children().first());
            }
        }else{
            this.moveToEnd($input.children().first());
        }       
    } else {
        //取 prevSectionId,nextSectionId 进行恢复选区
        if (newSections.length === 0) {
            if (rec.prevSectionId) {
                startSection = $input.children("#" + rec.prevSectionId);
                if (startSection.length === 0) {
                    startSection = undefined;
                }
            }
            if (rec.nextSectionId) {
                endSection = $input.children("#" + rec.nextSectionId);
                if (endSection.length === 0) {
                    endSection = undefined;
                }
            }
        } else {
            startSection = newSections[0];
            if (newSections.length > 1) {
                endSection = newSections[1];
            } else {
                endSection = startSection;
            }
        }
        if (!startSection || !endSection) {
            console.log("恢复选区无效！");
            return;
        }
        //先从开始段落查询选区的开始/结束节点
        firstChild = startSection.find("#" + startId);
        endChild = endSection.find("#" + endId);

        //如果没有找到则从结束段落里面取
        if (firstChild.length === 0) {
            firstChild = endSection.find("#" + startId);
        }
        if (endChild.length === 0) {
            endChild = endSection.find("#" + endId);
        }
        this._clearRangeRecord();
        var parent;
        if (firstChild.length > 0 && endChild.length > 0) {
            parent = firstChild;
            firstChild = firstChild[0].firstChild;
            endChild = endChild[0].lastChild;
            this.setCrossRange(firstChild, endChild, rangeOfs.startOffset, rangeOfs.endOffset);
        }
        //补充回激活对象
        //startSection endSection中是否存在table对象            
        if (parent && startSection[0].firstChild.nodeName === "TABLE" || endSection[0].firstChild.nodeName === "TABLE") {
            var objectTag;
            while (parent.length > 0 && parent[0].tagName !== "DIV") {
                if (parent[0].tagName === "TABLE") {
                    objectTag = parent;
                }
                parent = parent.parent();
            }
            if (objectTag) { //找到了对象
                this.clickActivedObject = objectTag.data("object");
            }
        }
    }
};

/**
 *重置undo、redo 
**/
Kedit.prototype.resetUndoRedo = function () {
    this.undoStack.clear();
    this.redoStack.clear();
};

/**
*压入一个撤销, 不清理redo ，撤销记录存放在this["undoRedoRec"]
* notClearRedo 不清理redo 
* nextRec:记录,如果传参 ，则优先nextRec 
**/
Kedit.prototype._putUndoNotClearRedo = function (nextRec) {
    var rec = this["undoRedoRec"];
    this["undoRedoRec"] = undefined;
    if (nextRec) {
        rec = nextRec;
    }
    if (rec) {
        this.undoStack.push(rec);
        this._undoRedoNotify("undo");
        return true;
    }
    return false;
};

/***
 * 按鼠标焦点所在段落提取undo记录，并putUndo
 * ***/
Kedit.prototype.putUndoByFocus = function(){
    this._makeUndoDataByFocus();
    this._putUndo();
};
/**
*压入一个撤销，撤销记录存放在this["undoRedoRec"]
* 并清理redo 
* nextRec:记录,如果传参 ，则优先nextRec 
**/
Kedit.prototype._putUndo = function (nextRec) {
    if (this._putUndoNotClearRedo(nextRec)) {
        this.redoStack.clear(); //一旦有undo进来，redo必须清理
        this._undoRedoNotify("redo");
    }
};
/***
 * 压入一个redo this["undoRedoRec"]
 * nextRec:记录,如果传参 ，则优先nextRec 
 * ***/
Kedit.prototype._putRedo = function (nextRec) {
    var rec = this["undoRedoRec"];
    this["undoRedoRec"] = undefined;
    if (nextRec) {
        rec = nextRec;
    }
    if (rec) {
        this.redoStack.push(rec);
        this._undoRedoNotify("redo");
    }
};
/***连续操作下，利用timeout delay毫秒（默认500）
 *  保证只压入一次undo
 *  delay = 0 表示不延时  
 * ***/
Kedit.prototype._putUndoDelayed = function (delay) {
    var timer = 600;
    if (delay === 0) {
        this._putUndo();
    } else {
        if (typeof delay !== "undefined") {
            timer = delay;
        }
        clearTimeout(this["_putUndoTimer"]);
        var _this = this;
        this["_putUndoTimer"] = setTimeout(function () {
            _this._putUndo();
        }, timer);
    }
};
/**清理this["undoRedoRec"]**/
Kedit.prototype._clearUndoRedoRecVar = function () {
    this["undoRedoRec"] = undefined;
};
/**
 * 创建撤销重做里当前的选区记录
 * ***/
Kedit.prototype._makeUndoRedoRangeRec = function(rec){
    if (this.range) {//如果有选区,则需要恢复选区
        var startContainer = this.range.startContainer; //开始节点
        var endContainer = this.range.endContainer; //结束节点 
        var startNode = $(startContainer.parentNode);
        var endNode = $(endContainer.parentNode);
        var startId = startNode.attr("id");
        var endId = endNode.attr("id");
        rec["startRegionId"] = startId;
        rec["endRegionId"] = endId;
        rec["rangeOfs"] = {
            startOffset: this.range.startOffset,
            endOffset: this.range.endOffset
        };
    }
};
/***
 * 创建undo/redo记录by 开始/结束段落
 * ***/
Kedit.prototype._makeUndoRedoDataByPelement = function (startPelment, endEelement) {
    /**已经存在的没有压栈的记录**/
    if (this["undoRedoRec"]) {
        return this["undoRedoRec"];
    }
    var inputId = this.$input.attr("id");
    var rec = {
        startRegionId: undefined,
        endRegionId: undefined,
        rangeOfs: undefined,
        replaceSectionId: [],
        html: [],
        inputId: inputId,
        prevSectionId: undefined,
        nextSectionId: undefined
    };
    var prevPel = startPelment.prev();
    var nextPel = endEelement.next();
    if (prevPel.length > 0) {
        rec.prevSectionId = prevPel.attr("id");
    }
    if (nextPel.length > 0) {
        rec.nextSectionId = nextPel.attr("id");
    }
    var tmpEl = startPelment;
    rec.replaceSectionId.push(tmpEl.attr("id"));
    rec.html.push(tmpEl[0].outerHTML);
    while (tmpEl.length > 0 && tmpEl[0] !== endEelement[0]) {
        tmpEl = tmpEl.next();
        rec.replaceSectionId.push(tmpEl.attr("id"));
        rec.html.push(tmpEl[0].outerHTML);
    }
    this._makeUndoRedoRangeRec(rec);
    return rec;
};
/***
 * 创建当前el节点所在段落的undo记录
 * ***/
Kedit.prototype._putUndoDataByNodeEl = function (el){   
    var pelement = this._findNodePElement(el);
    var rec = this._makeUndoRedoDataByPelement(pelement,pelement);
    this._putUndo(rec);
};

/**
 * 根据鼠标所在的焦点，以段落为重做、撤销恢复单位
 * startContainer、endContainer必定为文本节点
 * 记录选区位置内所有段落的html到待恢复的html数组中
 * isClear:是否是清空操作
 * rec={
 * startRegionId:选区的开始节点id,
 * endRegionId:选区的结束节点id ,
 * rangeOfs = { startOffset : 选区开始节点的下标索引 , endOffset: 选区结束节点的下标索引}
 * replaceSectionId = [被操作段落id集合] ,
 * html:[被操作的段落html集合],
 * inputId: 如果是浮动文本，则为浮动文本输入框的id，否则为空
 * isClear:是否是清除操作,
 * prevSectionId: 被操作段落选区的前一个段落（如果存在）, 应对选区所有段落被完整删除场景
 * nextSectionId: 被操作段落选区的下一个段落（如果存在）, 应对选区所有段落被完整删除场景
 * }
 * ***/
Kedit.prototype._makeUndoDataByFocus = function (isClear) {
    //console.log("_makeUndoDataByFocus  >>>>>>");
    /**已经存在的没有压栈的记录**/
    if (this["undoRedoRec"]) {
        return this["undoRedoRec"];
    }
    var prevPEle, nextPEle;
    var inputId = this.$input.attr("id");
    var rec = {
        isClear:isClear,
        startRegionId: undefined,
        endRegionId: undefined,
        rangeOfs: undefined,
        replaceSectionId: [],
        html: [],
        inputId: inputId,
        prevSectionId: undefined,
        nextSectionId: undefined
    };
    var _this = this;
    this._makeUndoRedoRangeRec(rec);
    if (isClear) {//如果是清除
        this._makeClearRec(rec);
    } else {
        if (this.clickActivedObject && this.clickActivedObject.jqObj) { //修饰的是表格、图片等对象
            var ele = this.clickActivedObject.jqObj.parent();
            while (ele.length > 0) {
                if (ele.hasClass("_section_div_")) {
                    break;
                }
                ele = ele.parent();
            }
            rec["replaceSectionId"].push(ele.attr("id"));
            rec["html"].push(ele[0].outerHTML);
            prevPEle = ele.prev();
        } else {
            this._getRangeSections(function (p) {
                if (!prevPEle) {
                    prevPEle = p.prev();
                }
                rec["html"].push(p[0].outerHTML);
                rec["replaceSectionId"].push(p.attr("id"));
                nextPEle = p.next();
            });
        }
    }
    //补充上 选区范围内的 前后段落 ID 记录（如果存在！）
    if (prevPEle && prevPEle.length > 0) {
        rec.prevSectionId = prevPEle.attr("id");
    }
    if (nextPEle && nextPEle.length > 0) {
        rec.nextSectionId = nextPEle.attr("id");
    }
    this["undoRedoRec"] = rec;    
    return rec;
};
/**
 * 创建一个清空记录
 * ***/
Kedit.prototype._makeClearRec = function (rec) {
    var childs = this.$fixInput.children("div");
    var _this = this;
    childs.each(function () {
        var $p = $(this);  
        rec.html.push($p[0].outerHTML);
        rec.replaceSectionId.push($p.attr("id"));
    });
    rec["floatItems"] = [];//补充上浮动文本/图片
    this.$inputWrap.children(".k_edit_float_panel").each(function () {
        var $tag = $(this).clone();
        $tag.children(".k_editor_float_input").removeAttr("contenteditable");
        var phtml = $tag[0].outerHTML.replace(/cursor:\s*((?!;).)+;/g, "");
        rec["floatItems"].push(phtml);
    });
    // if (!this.range){//恢复第一个段落为光标段落           
    // }
};
/***
 * 删除面板时候，将浮动面板压入撤销记录
 * jqObj : 面板jq对象
 * ***/
Kedit.prototype.putFlowPanel2Undo = function (jqObj) {
    //console.log("putFlowPanel2Undo >>>>>");
    var _this = this;
    var rec = {
        isFloat: true,    
        rebuild: true,   
        id: jqObj.attr("id"), 
        html: jqObj[0].outerHTML
    };
    this._putUndo(rec);
};
   $B["Edit"] = Kedit;
}));